feat: add etherfi spoke contract to restrict borrows to only etherfi safes#209
feat: add etherfi spoke contract to restrict borrows to only etherfi safes#209shivam-ef wants to merge 3 commits into
Conversation
….fi safes Requires the one-line aave-v4 patch (Spoke.borrow -> public virtual) carried on the local submodule branch etherfi/v0.5.11-gated-borrow; the submodule pin lands once the etherfi-protocol/aave-v4 fork is published. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AaveV4Fixture now deploys the gated spoke (matching the planned whitelabel instance) and takes the data provider feeding its isEtherFiSafe check. The two tests simulating third-party borrow pressure mark those actors as safes. GatedBorrow.t.sol proves the gating invariant: non-safes cannot borrow directly or via a position manager, while supply/withdraw/liquidation stay permissionless. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he whitelabel treasury Owns the TreasurySpoke (2-step handshake), claims accrued fees via withdraw and splits them between two immutable recipients; claim/split are permissionless. Owner-gated escape hatch can hand the TreasurySpoke to a new owner (flagged to Aave to keep or strike). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
| } | ||
|
|
||
| /// @notice Borrows `amount` of reserve `reserveId` for `onBehalfOf`, which must be an ether.fi safe | ||
| function borrow(uint256 reserveId, uint256 amount, address onBehalfOf) public override returns (uint256, uint256) { |
There was a problem hiding this comment.
borrow cannot override the Aave version pinned in this repo because the parent function is not virtual. the lend test job fails to compile here, so none of the new lend tests run. we'll need to include the required Aave change in this PR and update the pinned Aave version.
|
|
||
| /// @notice Borrows `amount` of reserve `reserveId` for `onBehalfOf`, which must be an ether.fi safe | ||
| function borrow(uint256 reserveId, uint256 amount, address onBehalfOf) public override returns (uint256, uint256) { | ||
| if (!etherFiDataProvider.isEtherFiSafe(onBehalfOf)) revert OnlyEtherFiSafe(onBehalfOf); |
There was a problem hiding this comment.
How about we also check that msg.sender is the LendGateway? The check would make sure all borrows go through the gateway rules.
There was a problem hiding this comment.
I think safe is fine, so if we have new contracts in the future trying to do something similar to gateway, it would still work
Note
High Risk
Borrow gating and treasury-owned fee routing are core to whitelabel economics and who can take debt; misconfiguration or a flawed
isEtherFiSafecheck could block legitimate users or allow unauthorized borrows.Overview
Introduces the whitelabel Aave v4 spoke and fee-splitting plumbing for the planned ether.fi instance, plus lend-profile tests that deploy the gated spoke instead of stock
SpokeInstance.EtherFiSpokeInstanceoverridesborrowsoonBehalfOfmust passIEtherFiDataProvider.isEtherFiSafe; supply, withdraw, repay, and liquidation stay unchanged. The data provider is an immutable constructor arg so borrow policy is enforced for gateway and direct self-service paths alike.AaveV4RevenueSplitteris meant to own the instanceTreasurySpoke, expose permissionlessclaimAndSplit(withdraw from treasury then split by fixed BPS), and give the splitter owner a two-step escape hatch to transfer treasury ownership.Build / tests: default Foundry profile now also skips
src/aave-v4/**.AaveV4Fixture._deployAaveV4takes anetherFiDataProviderand deploysEtherFiSpokeInstance. Gateway setup uses the realdataProvider; lens tests mock all addresses as safes; withdrawal accrual tests mock a second borrower as a safe. NewGatedBorrowandRevenueSplitterfork tests cover gating invariants and 80/20 fee flow.Reviewed by Cursor Bugbot for commit d20f00b. Bugbot is set up for automated code reviews on this repo. Configure here.