Skip to content

Commit

Permalink
drop legacy repay
Browse files Browse the repository at this point in the history
  • Loading branch information
itofarina committed Dec 5, 2024
1 parent 98b2bc4 commit b1c6d95
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 205 deletions.
125 changes: 61 additions & 64 deletions contracts/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,70 +1,67 @@
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 3572307, ~: 3478741)
ExaPluginTest:test_collectCredit_collects() (gas: 920580)
ExaPluginTest:test_collectCredit_collects_whenHealthFactorHigherThanMinHealthFactor() (gas: 801206)
ExaPluginTest:test_collectCredit_collects_withEnoughSlippage() (gas: 799697)
ExaPluginTest:test_collectCredit_passes_whenProposalLeavesEnoughLiquidity() (gas: 1009729)
ExaPluginTest:test_collectCredit_reverts_asNotKeeper() (gas: 362829)
ExaPluginTest:test_collectCredit_reverts_whenDisagreement() (gas: 555422)
ExaPluginTest:test_collectCredit_reverts_whenExpired() (gas: 358527)
ExaPluginTest:test_collectCredit_reverts_whenHealthFactorLowerThanMinHealthFactor() (gas: 831337)
ExaPluginTest:test_collectCredit_reverts_whenPrposalCausesInsufficientLiquidity() (gas: 1010021)
ExaPluginTest:test_collectCredit_reverts_whenReplay() (gas: 842864)
ExaPluginTest:test_collectCredit_reverts_whenTimelocked() (gas: 355190)
ExaPluginTest:test_collectCredit_toleratesTimeDrift() (gas: 803172)
ExaPluginTest:test_collectDebit_collects() (gas: 651898)
ExaPluginTest:test_collectDebit_collects_whenProposalLeavesEnoughLiquidity() (gas: 855472)
ExaPluginTest:test_collectDebit_reverts_asNotKeeper() (gas: 362639)
ExaPluginTest:test_collectDebit_reverts_whenExpired() (gas: 358289)
ExaPluginTest:test_collectDebit_reverts_whenProposalCausesInsufficientLiquidity() (gas: 852433)
ExaPluginTest:test_collectDebit_reverts_whenReplay() (gas: 691278)
ExaPluginTest:test_collectDebit_reverts_whenTimelocked() (gas: 354887)
ExaPluginTest:test_collectDebit_toleratesTimeDrift() (gas: 651929)
ExaPluginTest:test_collectInstallments_collects() (gas: 1338970)
ExaPluginTest:test_collectInstallments_revertsWhenNoSlippage() (gas: 1203024)
ExaPluginTest:test_collectInstallments_reverts_asNotKeeper() (gas: 363679)
ExaPluginTest:test_collectInstallments_reverts_whenExpired() (gas: 360687)
ExaPluginTest:test_collectInstallments_reverts_whenReplay() (gas: 1070873)
ExaPluginTest:test_collectInstallments_reverts_whenTimelocked() (gas: 357181)
ExaPluginTest:test_collectInstallments_toleratesTimeDrift() (gas: 1195583)
ExaPluginTest:test_crossRepay_repays() (gas: 20528543)
ExaPluginTest:test_crossRepay_repays_whenKeeper() (gas: 20518558)
ExaPluginTest:test_crossRepay_reverts_whenNotKeeper() (gas: 18861168)
ExaPluginTest:test_debitCollateral_collects() (gas: 20669875)
ExaPluginTest:test_exitMarket_reverts() (gas: 389331)
ExaPluginTest:test_lifiSwap_reverts_withDisagreement() (gas: 18030699)
ExaPluginTest:test_lifiSwap_swaps() (gas: 17747148)
ExaPluginTest:test_onUninstall_uninstalls() (gas: 292270)
ExaPluginTest:test_poke() (gas: 316002)
ExaPluginTest:test_pokeETH_deposits() (gas: 393056)
ExaPluginTest:test_propose_emitsProposed() (gas: 218792)
ExaPluginTest:test_refund_refunds() (gas: 361557)
ExaPluginTest:test_repayX_partiallyRepays() (gas: 1250526)
ExaPluginTest:test_repayX_partiallyRepays_whenKeeper() (gas: 1192596)
ExaPluginTest:test_repayX_repays() (gas: 1166741)
ExaPluginTest:test_repayX_repays_whenKeeper() (gas: 1108820)
ExaPluginTest:test_repay_partiallyRepays() (gas: 1782259)
ExaPluginTest:test_repay_repays() (gas: 1182416)
ExaPluginTest:test_repay_repays_whenKeeper() (gas: 1124572)
ExaPluginTest:test_rollDebt_rolls() (gas: 1233094)
ExaPluginTest:test_setCollector_emitsCollectorSet() (gas: 40443)
ExaPluginTest:test_setCollector_reverts_whenAddressZero() (gas: 32228)
ExaPluginTest:test_setCollector_reverts_whenNotAdmin() (gas: 33758)
ExaAccountFactoryTest:testFuzz_createAccount_EOAOwners(uint256,address[63]) (runs: 256, μ: 3563445, ~: 3436081)
ExaPluginTest:test_collectCredit_collects() (gas: 920206)
ExaPluginTest:test_collectCredit_collects_whenHealthFactorHigherThanMinHealthFactor() (gas: 800832)
ExaPluginTest:test_collectCredit_collects_withEnoughSlippage() (gas: 799411)
ExaPluginTest:test_collectCredit_passes_whenProposalLeavesEnoughLiquidity() (gas: 1009267)
ExaPluginTest:test_collectCredit_reverts_asNotKeeper() (gas: 362543)
ExaPluginTest:test_collectCredit_reverts_whenDisagreement() (gas: 555202)
ExaPluginTest:test_collectCredit_reverts_whenExpired() (gas: 358241)
ExaPluginTest:test_collectCredit_reverts_whenHealthFactorLowerThanMinHealthFactor() (gas: 831051)
ExaPluginTest:test_collectCredit_reverts_whenPrposalCausesInsufficientLiquidity() (gas: 1009559)
ExaPluginTest:test_collectCredit_reverts_whenReplay() (gas: 842468)
ExaPluginTest:test_collectCredit_reverts_whenTimelocked() (gas: 354860)
ExaPluginTest:test_collectCredit_toleratesTimeDrift() (gas: 802776)
ExaPluginTest:test_collectDebit_collects() (gas: 651524)
ExaPluginTest:test_collectDebit_collects_whenProposalLeavesEnoughLiquidity() (gas: 855054)
ExaPluginTest:test_collectDebit_reverts_asNotKeeper() (gas: 362353)
ExaPluginTest:test_collectDebit_reverts_whenExpired() (gas: 358025)
ExaPluginTest:test_collectDebit_reverts_whenProposalCausesInsufficientLiquidity() (gas: 851993)
ExaPluginTest:test_collectDebit_reverts_whenReplay() (gas: 691013)
ExaPluginTest:test_collectDebit_reverts_whenTimelocked() (gas: 354623)
ExaPluginTest:test_collectDebit_toleratesTimeDrift() (gas: 651641)
ExaPluginTest:test_collectInstallments_collects() (gas: 1338486)
ExaPluginTest:test_collectInstallments_revertsWhenNoSlippage() (gas: 1202584)
ExaPluginTest:test_collectInstallments_reverts_asNotKeeper() (gas: 363415)
ExaPluginTest:test_collectInstallments_reverts_whenExpired() (gas: 360401)
ExaPluginTest:test_collectInstallments_reverts_whenReplay() (gas: 1070389)
ExaPluginTest:test_collectInstallments_reverts_whenTimelocked() (gas: 356984)
ExaPluginTest:test_collectInstallments_toleratesTimeDrift() (gas: 1195121)
ExaPluginTest:test_crossRepay_repays() (gas: 20017889)
ExaPluginTest:test_crossRepay_repays_whenKeeper() (gas: 20008018)
ExaPluginTest:test_crossRepay_reverts_whenNotKeeper() (gas: 18350629)
ExaPluginTest:test_debitCollateral_collects() (gas: 20159006)
ExaPluginTest:test_exitMarket_reverts() (gas: 389045)
ExaPluginTest:test_lifiSwap_reverts_withDisagreement() (gas: 17523653)
ExaPluginTest:test_lifiSwap_swaps() (gas: 17240058)
ExaPluginTest:test_onUninstall_uninstalls() (gas: 284122)
ExaPluginTest:test_poke() (gas: 315694)
ExaPluginTest:test_pokeETH_deposits() (gas: 392792)
ExaPluginTest:test_propose_emitsProposed() (gas: 218704)
ExaPluginTest:test_refund_refunds() (gas: 361535)
ExaPluginTest:test_repay_partiallyRepays() (gas: 1249846)
ExaPluginTest:test_repay_partiallyRepays_whenKeeper() (gas: 1192016)
ExaPluginTest:test_repay_repays() (gas: 1165942)
ExaPluginTest:test_repay_repays_whenKeeper() (gas: 1108251)
ExaPluginTest:test_rollDebt_rolls() (gas: 1232549)
ExaPluginTest:test_setCollector_emitsCollectorSet() (gas: 40531)
ExaPluginTest:test_setCollector_reverts_whenAddressZero() (gas: 32206)
ExaPluginTest:test_setCollector_reverts_whenNotAdmin() (gas: 33736)
ExaPluginTest:test_setCollector_sets_whenAdmin() (gas: 39832)
ExaPluginTest:test_setMinHealthFactor_reverts_whenLowerThanWad() (gas: 32133)
ExaPluginTest:test_setMinHealthFactor_reverts_whenLowerThanWad() (gas: 32200)
ExaPluginTest:test_setMinHealthFactor_reverts_whenNotAdmin() (gas: 33724)
ExaPluginTest:test_setMinHealthFactor_sets_whenAdmin() (gas: 39345)
ExaPluginTest:test_withdrawWETH_transfersETH() (gas: 865650)
ExaPluginTest:test_withdraw_reverts_whenNoProposal() (gas: 415257)
ExaPluginTest:test_withdraw_reverts_whenNoProposalKeeper() (gas: 358072)
ExaPluginTest:test_withdraw_reverts_whenNotKeeper() (gas: 355090)
ExaPluginTest:test_withdraw_reverts_whenReceiverIsContractAndMarketNotWETH() (gas: 621309)
ExaPluginTest:test_withdraw_reverts_whenTimelocked() (gas: 307603)
ExaPluginTest:test_withdraw_reverts_whenTimelockedKeeper() (gas: 309416)
ExaPluginTest:test_withdraw_reverts_whenWrongAmount() (gas: 308570)
ExaPluginTest:test_withdraw_reverts_whenWrongMarket() (gas: 309304)
ExaPluginTest:test_withdraw_reverts_whenWrongReceiver() (gas: 308239)
ExaPluginTest:test_withdraw_transfersAsset_asKeeper() (gas: 820262)
ExaPluginTest:test_withdraw_transfersAsset_asOwner() (gas: 818976)
ExaPluginTest:test_withdrawWETH_transfersETH() (gas: 865188)
ExaPluginTest:test_withdraw_reverts_whenNoProposal() (gas: 414905)
ExaPluginTest:test_withdraw_reverts_whenNoProposalKeeper() (gas: 357764)
ExaPluginTest:test_withdraw_reverts_whenNotKeeper() (gas: 354804)
ExaPluginTest:test_withdraw_reverts_whenReceiverIsContractAndMarketNotWETH() (gas: 620913)
ExaPluginTest:test_withdraw_reverts_whenTimelocked() (gas: 307471)
ExaPluginTest:test_withdraw_reverts_whenTimelockedKeeper() (gas: 309262)
ExaPluginTest:test_withdraw_reverts_whenWrongAmount() (gas: 308438)
ExaPluginTest:test_withdraw_reverts_whenWrongMarket() (gas: 309172)
ExaPluginTest:test_withdraw_reverts_whenWrongReceiver() (gas: 308107)
ExaPluginTest:test_withdraw_transfersAsset_asKeeper() (gas: 819800)
ExaPluginTest:test_withdraw_transfersAsset_asOwner() (gas: 818536)
InstallmentsPreviewerTest:test_preview_returns() (gas: 135598)
RefunderTest:test_refund_refunds() (gas: 242379)
RefunderTest:test_refund_reverts_whenExpired() (gas: 69144)
Expand Down
107 changes: 26 additions & 81 deletions contracts/src/ExaPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,34 +112,7 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
emit Proposed(msg.sender, market, receiver, amount, block.timestamp + PROPOSAL_DELAY);
}

function repay(uint256 maturity) external {
uint256 positionAssets;
uint256 maxRepay;
(positionAssets, maxRepay) = _previewRepay(maturity);

uint256 amount = maxRepay.min(EXA_USDC.maxWithdraw(msg.sender));
positionAssets = positionAssets.min(EXA_USDC.maxWithdraw(msg.sender));
bytes memory data = _hash(
abi.encodePacked(
bytes1(0x01),
abi.encode(
RepayCallbackData({
maturity: maturity,
borrower: msg.sender,
positionAssets: positionAssets.min(EXA_USDC.maxWithdraw(msg.sender)),
maxRepay: amount
})
)
)
);

IPluginExecutor(msg.sender).executeFromPluginExternal(
address(EXA_USDC), 0, abi.encodeCall(IERC20.approve, (address(this), EXA_USDC.previewWithdraw(amount)))
);
_flashLoan(amount, data);
}

function repayX(uint256 maturity, uint256 positionAssets, uint256 maxRepay) external {
function repay(uint256 maturity, uint256 positionAssets, uint256 maxRepay) external {
bytes memory data = _hash(
abi.encodePacked(
bytes1(0x01),
Expand Down Expand Up @@ -461,22 +434,21 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {

/// @inheritdoc BasePlugin
function pluginManifest() external pure override returns (PluginManifest memory manifest) {
manifest.executionFunctions = new bytes4[](15);
manifest.executionFunctions = new bytes4[](14);
manifest.executionFunctions[0] = this.propose.selector;
manifest.executionFunctions[1] = this.repay.selector;
manifest.executionFunctions[2] = this.repayX.selector;
manifest.executionFunctions[3] = this.crossRepay.selector;
manifest.executionFunctions[4] = this.rollDebt.selector;
manifest.executionFunctions[5] = bytes4(keccak256("collectCredit(uint256,uint256,uint256,bytes)"));
manifest.executionFunctions[6] = bytes4(keccak256("collectCredit(uint256,uint256,uint256,uint256,bytes)"));
manifest.executionFunctions[7] = this.collectDebit.selector;
manifest.executionFunctions[8] = this.collectCollateral.selector;
manifest.executionFunctions[9] = this.collectInstallments.selector;
manifest.executionFunctions[10] = this.lifiSwap.selector;
manifest.executionFunctions[11] = this.poke.selector;
manifest.executionFunctions[12] = this.pokeETH.selector;
manifest.executionFunctions[13] = this.withdraw.selector;
manifest.executionFunctions[14] = this.receiveFlashLoan.selector;
manifest.executionFunctions[2] = this.crossRepay.selector;
manifest.executionFunctions[3] = this.rollDebt.selector;
manifest.executionFunctions[4] = bytes4(keccak256("collectCredit(uint256,uint256,uint256,bytes)"));
manifest.executionFunctions[5] = bytes4(keccak256("collectCredit(uint256,uint256,uint256,uint256,bytes)"));
manifest.executionFunctions[6] = this.collectDebit.selector;
manifest.executionFunctions[7] = this.collectCollateral.selector;
manifest.executionFunctions[8] = this.collectInstallments.selector;
manifest.executionFunctions[9] = this.lifiSwap.selector;
manifest.executionFunctions[10] = this.poke.selector;
manifest.executionFunctions[11] = this.pokeETH.selector;
manifest.executionFunctions[12] = this.withdraw.selector;
manifest.executionFunctions[13] = this.receiveFlashLoan.selector;

ManifestFunction memory selfRuntimeValidationFunction = ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
Expand All @@ -498,7 +470,7 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
functionId: uint8(FunctionId.RUNTIME_VALIDATION_BALANCER),
dependencyIndex: 0
});
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](15);
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](14);
manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({
executionSelector: IExaAccount.propose.selector,
associatedFunction: selfRuntimeValidationFunction
Expand All @@ -508,54 +480,50 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
associatedFunction: keeperOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[2] = ManifestAssociatedFunction({
executionSelector: IExaAccount.repayX.selector,
associatedFunction: keeperOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[3] = ManifestAssociatedFunction({
executionSelector: IExaAccount.crossRepay.selector,
associatedFunction: keeperOrSelfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[4] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[3] = ManifestAssociatedFunction({
executionSelector: IExaAccount.lifiSwap.selector,
associatedFunction: selfRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[5] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[4] = ManifestAssociatedFunction({
executionSelector: IExaAccount.rollDebt.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[6] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[5] = ManifestAssociatedFunction({
executionSelector: bytes4(keccak256("collectCredit(uint256,uint256,uint256,bytes)")),
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[7] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[6] = ManifestAssociatedFunction({
executionSelector: bytes4(keccak256("collectCredit(uint256,uint256,uint256,uint256,bytes)")),
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[8] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[7] = ManifestAssociatedFunction({
executionSelector: IExaAccount.collectDebit.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[9] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[8] = ManifestAssociatedFunction({
executionSelector: IExaAccount.collectCollateral.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[10] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[9] = ManifestAssociatedFunction({
executionSelector: IExaAccount.collectInstallments.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[11] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[10] = ManifestAssociatedFunction({
executionSelector: IExaAccount.poke.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[12] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[11] = ManifestAssociatedFunction({
executionSelector: IExaAccount.pokeETH.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[13] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[12] = ManifestAssociatedFunction({
executionSelector: IExaAccount.withdraw.selector,
associatedFunction: keeperRuntimeValidationFunction
});
manifest.runtimeValidationFunctions[14] = ManifestAssociatedFunction({
manifest.runtimeValidationFunctions[13] = ManifestAssociatedFunction({
executionSelector: this.receiveFlashLoan.selector,
associatedFunction: balancerRuntimeValidationFunction
});
Expand Down Expand Up @@ -696,21 +664,6 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
BALANCER_VAULT.flashLoan(address(this), tokens, amounts, data);
}

function _fixedDepositYield(IMarket market, uint256 maturity, uint256 assets) internal view returns (uint256 yield) {
FixedPool memory pool = market.fixedPools(maturity);
if (maturity > pool.lastAccrual) {
pool.unassignedEarnings -=
pool.unassignedEarnings.mulDiv(block.timestamp - pool.lastAccrual, maturity - pool.lastAccrual);
}
uint256 backupFee = 0;
uint256 backupSupplied = pool.borrowed - (pool.borrowed < pool.supplied ? pool.borrowed : pool.supplied);
if (backupSupplied != 0) {
yield = pool.unassignedEarnings.mulDiv(assets < backupSupplied ? assets : backupSupplied, backupSupplied);
backupFee = yield.mulWad(market.backupFeeRate());
yield -= backupFee;
}
}

function _hash(bytes memory data) internal returns (bytes memory) {
callHash = keccak256(data);
return data;
Expand All @@ -733,14 +686,6 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
if (amountOut < minOut) revert Disagreement();
}

function _previewRepay(uint256 maturity) internal view returns (uint256 positionAssets, uint256 maxRepay) {
FixedPosition memory position = EXA_USDC.fixedBorrowPositions(maturity, msg.sender);
positionAssets = position.principal + position.fee;
maxRepay = block.timestamp < maturity
? positionAssets - _fixedDepositYield(EXA_USDC, maturity, position.principal)
: positionAssets + positionAssets.mulWad((block.timestamp - maturity) * EXA_USDC.penaltyRate());
}

modifier onlyMarket(IMarket market) {
_checkMarket(market);
_;
Expand Down
3 changes: 1 addition & 2 deletions contracts/src/IExaAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { IERC4626 } from "openzeppelin-contracts/contracts/interfaces/IERC4626.s

interface IExaAccount {
function propose(IMarket market, uint256 amount, address receiver) external;
function repay(uint256 maturity) external;
function repayX(uint256 maturity, uint256 positionAssets, uint256 maxRepay) external;
function repay(uint256 maturity, uint256 positionAssets, uint256 maxRepay) external;
function crossRepay(
uint256 maturity,
uint256 positionAssets,
Expand Down
Loading

0 comments on commit b1c6d95

Please sign in to comment.