Add BTCD sBTCD yield adapter#2705
Conversation
Pure on-chain ERC4626 share-price-growth adapter for the BTCD staking vault (sBTCD). Reads sBTCD.totalSupply for size, the on-chain SBTCDOracle (Chainlink-compatible, 8 decimals USD) for tvlUsd, and 7d share-price growth via convertToAssets(1e18) at current and historical blocks for apyBase. Single pool, no rewards (yield is auto-compounded into the share price via 8h linear vesting from the YieldDistributor). underlyingTokens = BTCD; pool id lowercased per yield-server convention. Note: the upstream PR is gated on BTCD being listed on DefiLlama's TVL page (DefiLlama-Adapters). Holding the merge here until that lands.
… sBTCD yield pool
…s and update variable names for clarity
Add SBTCD yield to Btcd
feat(btcd): remove cooldown mention from poolMeta in BTCD staking vault
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a new BTCD adapter exporting ChangesBTCD Adapter
Sequence DiagramsequenceDiagram
participant apy as apy()
participant sBTCD as sBTCD contract
participant Chainlink as Chainlink BTC/USD
participant RPC as Ethereum RPC / Block history
apy->>sBTCD: call totalAssets()
apy->>Chainlink: call latestRoundData()
apy->>RPC: computeApyBase() -> RPC: getBlockByTimestamp(lookback)
RPC->>sBTCD: call previewRedeem(1e18) at lookback block
RPC->>sBTCD: call previewRedeem(1e18) at latest block
apy->>apy: compute peg, apyBase, tvlUsd -> return [pool]
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The btcd adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/adaptors/btcd/index.js`:
- Around line 34-36: The getBlockAtTimestamp function calls axios.get without a
timeout and assumes response.data.height exists; modify getBlockAtTimestamp to
pass a sensible timeout option to axios.get (e.g., { timeout: 5000 }) and
validate the response before returning: ensure response and response.data exist
and that response.data.height is a finite number, otherwise throw or return a
clear error; reference the getBlockAtTimestamp function and the axios.get call
when making the change.
- Around line 96-103: The apy function's call to sdk.api.abi.call(..., abi:
totalAssetsAbi) can reject and cause Promise.all to fail; guard this by handling
failures for that specific call (either wrap the sdk.api.abi.call in a try/catch
before awaiting the other promises or use Promise.allSettled and treat a
rejected totalAssets result as zero), set a sensible default for
sBtcdAssetsRes.output (e.g. "0") so sBtcdTvlUsd calculation can continue, and
log the error; locate apy, sdk.api.abi.call with totalAssetsAbi, sBtcdAssetsRes
and sBtcdTvlUsd to apply the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3daefc63-1cab-450d-841e-5175faaf693f
📒 Files selected for processing (1)
src/adaptors/btcd/index.js
feat(btcd): enhance sBTCD adapter with vesting and cooldown duration …
|
The btcd adapter exports pools: Test Suites: 1 passed, 1 total |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/adaptors/btcd/index.js`:
- Line 50: The code dereferences properties on the result of lookupBlock (the
variable `old`) inside `apy()` without verifying the return shape; update calls
that use `old.block` and `old.timestamp` to first guard that `old` is an object
with numeric `block`/`timestamp` (e.g., `if (!old || typeof old.block !==
'number') return 0` or similarly validate and bail) before using
`SBTCD_YIELD_TURNED_ON_BLOCK` or computing time deltas; apply the same guard
where `old.timestamp` is read (and for any `new`/other lookupBlock results) so
unexpected shapes won't throw and will cause a safe early return or fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 76454f66-8d75-4e19-ba8d-7bbb0db38ede
📒 Files selected for processing (1)
src/adaptors/btcd/index.js
| } catch (e) { | ||
| return 0; | ||
| } | ||
| if (old.block < SBTCD_YIELD_TURNED_ON_BLOCK) return 0; |
There was a problem hiding this comment.
Guard lookupBlock output before dereferencing fields.
Line 50 and Line 78 use old.block / old.timestamp outside the lookup guard. If lookupBlock returns an unexpected shape (instead of throwing), this can throw here and cause apy() to fail via Promise.all.
Suggested fix
} catch (e) {
return 0;
}
+ if (
+ !Number.isFinite(latest?.timestamp) ||
+ !Number.isFinite(old?.timestamp) ||
+ !Number.isInteger(old?.block)
+ ) {
+ return 0;
+ }
if (old.block < SBTCD_YIELD_TURNED_ON_BLOCK) return 0;
@@
const rate = Number(rateScaled) / 1e18;
if (!isFinite(rate) || rate <= 0) return 0;
const secondsElapsed = latest.timestamp - old.timestamp;
if (secondsElapsed <= 0) return 0;Also applies to: 78-80
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/adaptors/btcd/index.js` at line 50, The code dereferences properties on
the result of lookupBlock (the variable `old`) inside `apy()` without verifying
the return shape; update calls that use `old.block` and `old.timestamp` to first
guard that `old` is an object with numeric `block`/`timestamp` (e.g., `if (!old
|| typeof old.block !== 'number') return 0` or similarly validate and bail)
before using `SBTCD_YIELD_TURNED_ON_BLOCK` or computing time deltas; apply the
same guard where `old.timestamp` is read (and for any `new`/other lookupBlock
results) so unexpected shapes won't throw and will cause a safe early return or
fallback.
|
The btcd adapter exports pools: Test Suites: 1 passed, 1 total |
… in sBTCD adapter
|
The btcd adapter exports pools: Test Suites: 1 passed, 1 total |
|
Actionable comments posted: 0 |
Adds the BTCD yield adapter for the Ethereum sBTCD staking vault only.
Exposes the sBTCD ERC-4626 vault
Computes TVL from on-chain totalAssets()
Computes base APY from 30-day previewRedeem() growth
Uses the BTCD underlying token and vault address metadata required by Yield Server
Summary by CodeRabbit