Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cantina contest fixes #262

Merged
merged 117 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
200ed48
restrict function visibility
MickdeGraaf Jun 4, 2024
cb446be
Named parameters in minters mapping
MickdeGraaf Jun 5, 2024
4884946
Use named imports
MickdeGraaf Jun 5, 2024
d6b6548
gas + code improvements
MickdeGraaf Jun 5, 2024
b3d074f
typo fix
MickdeGraaf Jun 5, 2024
9b79936
Emit events in state changing functions
MickdeGraaf Jun 5, 2024
807ecb7
Only gulp when sufficient shares are minted
MickdeGraaf Jun 6, 2024
4504852
Test gulp threshold
MickdeGraaf Jun 6, 2024
b10e73c
Allow withdraws and redeems when a controller is set
MickdeGraaf Jun 6, 2024
ddbd121
Add missing docstrings
MickdeGraaf Jun 4, 2024
0ffc50a
remove _withdraw override and throw original errors on redeem and wit…
MickdeGraaf Jun 6, 2024
7c56d35
Merge pull request #14 from euler-xyz/fix-OZ-Synth-L-03-final
MickdeGraaf Jul 2, 2024
afd1d41
Merge pull request #13 from euler-xyz/fix/OZ-Synths-CR-02
MickdeGraaf Jul 2, 2024
6f23ba7
Merge branch 'openzeppelin-synth-fixes' into fix/OZ-Synths-CR-01
MickdeGraaf Jul 2, 2024
0b43778
Merge pull request #12 from euler-xyz/fix/OZ-Synths-CR-01
MickdeGraaf Jul 2, 2024
e4d7c1d
Merge pull request #11 from euler-xyz/fix/OZ-Synths-N-11
MickdeGraaf Jul 2, 2024
fb336db
Merge pull request #10 from euler-xyz/fix/OZ-Synths-N-09
MickdeGraaf Jul 2, 2024
2ffe51c
Merge pull request #9 from euler-xyz/fix/OZ-Synths-N-08
MickdeGraaf Jul 2, 2024
141e528
Merge pull request #8 from euler-xyz/fix/OZ-Synth-N-06
MickdeGraaf Jul 2, 2024
9df0b7c
Merge branch 'openzeppelin-synth-fixes' into fix/OZ-Synth-N-05
MickdeGraaf Jul 2, 2024
8bcb032
Merge pull request #7 from euler-xyz/fix/OZ-Synth-N-05
MickdeGraaf Jul 2, 2024
561af00
Switch to named imports
MickdeGraaf Jun 5, 2024
818e1b2
Merge pull request #6 from euler-xyz/fix/OZ-Synth-N-03
MickdeGraaf Jul 2, 2024
06c82e7
Merge branch 'openzeppelin-synth-fixes' into fix/OZ-Synth-N-01-final
MickdeGraaf Jul 2, 2024
842c53d
Merge pull request #5 from euler-xyz/fix/OZ-Synth-N-01-final
MickdeGraaf Jul 2, 2024
7bd80ef
docstring fixes
MickdeGraaf Jun 4, 2024
439896f
formatting fix
MickdeGraaf Jul 2, 2024
d137421
Merge pull request #1 from euler-xyz/fix/OZ-Synth-L-02
MickdeGraaf Jul 2, 2024
d5ca0a2
Merge branch 'openzeppelin-synth-fixes' of https://github.com/euler-x…
kasperpawlowski Jul 2, 2024
c2779f2
chore: formatting
kasperpawlowski Jul 2, 2024
ca5fca5
fix: OZ L-04 (continuation)
kasperpawlowski Jul 3, 2024
52b1fb0
fix: formatting
kasperpawlowski Jul 3, 2024
3c22922
test: fix testFuzz_gulp_under_uint168
kasperpawlowski Jul 3, 2024
d57b84e
fix: formatting
kasperpawlowski Jul 3, 2024
6a30a60
feat: remove ERC20Collateral, add ERC20EVCCompatible
kasperpawlowski Jul 3, 2024
f8b969c
fix: change constructor param type
kasperpawlowski Jul 3, 2024
39a142e
feat: change transferFrom method order
kasperpawlowski Jul 3, 2024
27be669
chore: update specs
kasperpawlowski Jul 3, 2024
b3afaf4
chore: update specs
kasperpawlowski Jul 3, 2024
8edac49
remove unnecessary check for 0 length symbol/names
hoytech Jul 3, 2024
45c2932
fix: cantina 488
kasperpawlowski Jul 4, 2024
67533d4
fix: cantina 490
kasperpawlowski Jul 4, 2024
f97f20c
fix negative interest in transfer debt logs; remove return value from…
dglowinski Jul 5, 2024
a288f5e
fix: cantina 68
kasperpawlowski Jul 5, 2024
1724c05
fix: add comment
kasperpawlowski Jul 5, 2024
c2b0f20
fix: cantina 254
kasperpawlowski Jul 5, 2024
52c07b3
fix: cantina 207
kasperpawlowski Jul 5, 2024
07b8930
fix div zero in liquidation when liability value is zero
dglowinski Jul 5, 2024
c1144e6
fix: cantina 331
kasperpawlowski Jul 5, 2024
cca8a5d
allow calls to set allowance for self
dglowinski Jul 5, 2024
62ee16a
feat: remove ESR collateral feature
kasperpawlowski Jul 5, 2024
51cad4d
test: fix invariant_totalAssetsShouldBeEqualToBalanceAfterSMEAR, add …
kasperpawlowski Jul 5, 2024
45806ca
chore: update specs
kasperpawlowski Jul 5, 2024
b25a795
test: improve testFuzz_conditionalAccruedInterestUpdate
kasperpawlowski Jul 5, 2024
62c9053
remove clearLTV function
dglowinski Jul 6, 2024
dde6cc1
check for existing code in set implementation
dglowinski Jul 8, 2024
fbb91df
fix: prevent potential IRM underflow
kasperpawlowski Jul 8, 2024
49ec8d3
change checkAccountStatus function mutability
kasperpawlowski Jul 8, 2024
3f9468d
Cantina 520 - disallow 1e4 as max discount
dglowinski Jul 8, 2024
0c6b6a4
remove `initialized` from `LTVConfig`
dglowinski Jul 8, 2024
91b63f9
fix natspec
dglowinski Jul 8, 2024
7a45671
disable all vault operations on vault creation
dglowinski Jul 8, 2024
74e0e01
In setLTV(), attempt to price the collateral in order to detect self-…
hoytech Jul 8, 2024
679baa7
don't bother updating the vault in setLTV: can just get values direct…
hoytech Jul 9, 2024
e8f5374
remove error
dglowinski Jul 15, 2024
d366c8d
update specs
dglowinski Jul 15, 2024
379a256
move deposit call to module
dglowinski Jul 15, 2024
ead25cb
fix: OZ L-04 (continuation)
kasperpawlowski Jul 16, 2024
468681d
feat: make ESynth governance functions consistent with the EVK
kasperpawlowski Jul 18, 2024
260a177
Merge pull request #29 from euler-xyz/esynth-governance-consistency
dglowinski Jul 30, 2024
0924a42
Merge pull request #28 from euler-xyz/delegate-deposit
dglowinski Jul 30, 2024
1f258c5
Merge pull request #26 from euler-xyz/141-block-unpriceable-collateral
dglowinski Jul 30, 2024
94aeaee
Merge pull request #25 from euler-xyz/default-disable-ops
dglowinski Jul 30, 2024
602ca34
Merge pull request #24 from euler-xyz/520-max-liq-discount
dglowinski Jul 30, 2024
50c5c90
Merge pull request #22 from euler-xyz/irm-underflow
dglowinski Jul 30, 2024
8eed9ff
Merge pull request #23 from euler-xyz/check-account-status-mutability
dglowinski Jul 30, 2024
b5fc6f2
Merge pull request #21 from euler-xyz/320-setImplementation-check-code
dglowinski Jul 30, 2024
5824544
Merge pull request #20 from euler-xyz/remove-clearLTV
dglowinski Jul 30, 2024
6d8747e
Merge pull request #18 from euler-xyz/67-self-allowance
dglowinski Jul 30, 2024
47188d2
Merge pull request #17 from euler-xyz/cantina-331
dglowinski Jul 30, 2024
2f935f5
Merge pull request #16 from euler-xyz/43/508-liquidation-panic
dglowinski Jul 30, 2024
c15f0e8
Merge pull request #15 from euler-xyz/cantina-207
dglowinski Jul 30, 2024
e0d22ca
Merge pull request #14 from euler-xyz/cantina-254
dglowinski Jul 30, 2024
06cc3c0
Merge pull request #13 from euler-xyz/cantina-68
dglowinski Jul 30, 2024
50deb12
Merge pull request #12 from euler-xyz/75-negative-interest
dglowinski Jul 30, 2024
a92a2fb
Merge pull request #9 from euler-xyz/cantina-490
dglowinski Jul 30, 2024
45f9f50
Merge pull request #8 from euler-xyz/cantina-488
dglowinski Jul 30, 2024
b62b529
Merge pull request #5 from euler-xyz/name-symbol-fixes
dglowinski Jul 30, 2024
ad8e912
Merge pull request #3 from euler-xyz/pull-token-order
dglowinski Jul 30, 2024
9798ccd
Cantina 125 - fix comment in checkLiquidity
dglowinski Jul 8, 2024
4a6d5eb
Cantina 79 - fix comment in IRMSynth
dglowinski Jul 8, 2024
9940555
Cantina 85 - add comment about modules deployment
dglowinski Jul 8, 2024
819262a
improve maxLiquidationDiscount natspec
dglowinski Jul 8, 2024
3f1bff1
Cantina 89 - fix ESR.withdraw natspec
dglowinski Jul 8, 2024
daf525f
Cantina 116 - fix DToken.symbol spec
dglowinski Jul 8, 2024
32e2097
Cantina 117 - update viewDelegate specs
dglowinski Jul 8, 2024
9c28d48
Cantina 150 - improve setInterestRateModel natspec
dglowinski Jul 8, 2024
390c0b9
Cantina 447 - improve natspec for repayWithShares
dglowinski Jul 8, 2024
b3723cb
Cantina 169 - fix pushAssets natspec
dglowinski Jul 8, 2024
dc55976
Cantina 199 - fix typo in IRMSynth constructor
dglowinski Jul 8, 2024
551f2bf
Cantina 206 - fix protocolFeeShare natspec
dglowinski Jul 8, 2024
7730f7b
Cantina 220 - improve liquidation slippage params natspec
dglowinski Jul 8, 2024
bd3b727
Cantina 551 - add comment about multiple repays above supply cap
dglowinski Jul 15, 2024
7680f9f
formatting
dglowinski Jul 15, 2024
3289803
improve checkLiquidity comment
dglowinski Jul 16, 2024
35f3312
Merge pull request #27 from euler-xyz/cantina-docs-fixes
dglowinski Jul 30, 2024
e44d442
add min liability value for socialization
dglowinski Jul 5, 2024
337b6de
fix: cantina 111 & 477
kasperpawlowski Jul 4, 2024
4ed81e7
test: improve
kasperpawlowski Jul 5, 2024
96d81c8
fix: revert cantina 111
kasperpawlowski Jul 18, 2024
4710cc8
Merge pull request #11 from euler-xyz/368-plummet-xr-simple
dglowinski Jul 30, 2024
3c79e34
Merge pull request #10 from euler-xyz/cantina-111-477
dglowinski Jul 30, 2024
aa8db73
Merge branch 'master' into remove-erc20-collateral
kasperpawlowski Jul 30, 2024
7d23acc
Merge pull request #2 from euler-xyz/remove-erc20-collateral
dglowinski Jul 31, 2024
e621820
Merge branch 'master' into cantina-contest-fixes
dglowinski Jul 31, 2024
3883206
fix: natspec typos
kasperpawlowski Aug 7, 2024
0262f34
fix: whitepaper typo
kasperpawlowski Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/ethereum-vault-connector"]
path = lib/ethereum-vault-connector
url = https://github.com/euler-xyz/ethereum-vault-connector
[submodule "lib/permit2"]
path = lib/permit2
url = https://github.com/Uniswap/permit2
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/ethereum-vault-connector"]
path = lib/ethereum-vault-connector
url = https://github.com/euler-xyz/ethereum-vault-connector
14 changes: 7 additions & 7 deletions docs/specs.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/whitepaper.md
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ In essence, a liquidation is equivalent to a stop-loss order. As long as you set

**This section is still a work-in-progress and is subject to change**

Since the EVK is a *kit*, it attempts to be maximally flexible and doesn't enforce policy decisions on vault creators. This means that it is possible to create vaults with insecure or malicious configurations. Furthermore, an otherwise secure vault may be insecure because it accapts an [insecure collateral as collateral](#untrusted-collaterals) (or a collateral vault itself accepts insecure collateral, etc, recursively).
Since the EVK is a *kit*, it attempts to be maximally flexible and doesn't enforce policy decisions on vault creators. This means that it is possible to create vaults with insecure or malicious configurations. Furthermore, an otherwise secure vault may be insecure because it accepts an [insecure collateral as collateral](#untrusted-collaterals) (or a collateral vault itself accepts insecure collateral, etc, recursively).

Perspectives provide a mechanism for validating properties of a vault using on-chain verifiable logic. A perspective is any contract that implements the following interface:

Expand Down
2 changes: 1 addition & 1 deletion lib/ethereum-vault-connector
Submodule ethereum-vault-connector updated 37 files
+1 −1 .github/workflows/checkrules.yml
+ audits/Euler Omniscia report.pdf
+ audits/Euler OpenZeppelin report.pdf
+ audits/Euler Spearbit report.pdf
+ audits/Euler yAudit report (EVC + EVK + Price Oracle).pdf
+ audits/Euler yAudit report (EVC).pdf
+2 −1 certora/conf/CER-1-Owner/CER-59-Owner-override.conf
+2 −1 certora/conf/CER-11-Controllers/CER-12-Controllers-number.conf
+2 −1 certora/conf/CER-15-Permit/CER-65-Permit-onBehalfOfAccount.conf
+2 −1 certora/conf/CER-2-Operator/CER-52-Operator-deauthorization.conf
+2 −1 certora/conf/CER-2-Operator/CER-68-Operator-authorization.conf
+2 −1 certora/conf/CER-27-ExecutionContext/CER-38-ExecutionContext-restored.conf
+2 −1 certora/conf/CER-44-VaultStatusCheck/CER-78-VaultStatusCheck-scheduling.conf
+2 −1 certora/conf/misc/MustRevertFunctions.conf
+1 −1 certora/harness/EthereumVaultConnectorHarness.sol
+2 −2 certora/specs/CER-11-Controllers/CER-12-Controllers-number.spec
+2 −1 certora/specs/CER-27-ExecutionContext/CER-38-ExecutionContext-restored.spec
+2 −5 certora/specs/CER-40-AccountStatusCheck/CER-41-AccountStatusCheck-OnlyOne.spec
+1 −2 certora/specs/CER-40-AccountStatusCheck/CER-42-AccountStatusCheck-NoController.spec
+2 −2 certora/specs/utils/IsLowLevelCallFunction.spec
+0 −1 certora/specs/utils/IsMustRevertFunction.spec
+13 −13 docs/specs.md
+1 −1 src/Errors.sol
+2 −2 src/EthereumVaultConnector.sol
+1 −1 src/Events.sol
+1 −1 src/ExecutionContext.sol
+1 −1 src/Set.sol
+1 −1 src/TransientStorage.sol
+1 −1 src/interfaces/IERC1271.sol
+6 −2 src/interfaces/IEthereumVaultConnector.sol
+1 −1 src/interfaces/IVault.sol
+31 −1 src/utils/EVCUtil.sol
+19 −5 test/invariants/EthereumVaultConnector.t.sol
+56 −0 test/unit/EVCUtil/EVCUtil.t.sol
+16 −0 test/unit/EthereumVaultConnector/POC.t.sol
+1 −0 test/unit/EthereumVaultConnector/Permit.t.sol
+1 −1 test/unit/EthereumVaultConnector/SetPermitDisabledMode.t.sol
3 changes: 3 additions & 0 deletions src/EVault/Dispatch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ abstract contract Dispatch is
address governance;
}

/// @notice EVault's constructor
/// @dev It is highly recommended to deploy fresh modules for every new EVault deployment. Particular care must
/// also be taken to ensure the modules are deployed with the exact same values of the `Integrations` struct.
constructor(Integrations memory integrations, DeployedModules memory modules) Base(integrations) {
MODULE_INITIALIZE = AddressUtils.checkContract(modules.initialize);
MODULE_TOKEN = AddressUtils.checkContract(modules.token);
Expand Down
8 changes: 3 additions & 5 deletions src/EVault/EVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ contract EVault is Dispatch {
function creator() public view virtual override useView(MODULE_VAULT) returns (address) {}


function deposit(uint256 amount, address receiver) public virtual override callThroughEVC returns (uint256) { return super.deposit(amount, receiver); }
function deposit(uint256 amount, address receiver) public virtual override callThroughEVC use(MODULE_VAULT) returns (uint256) {}

function mint(uint256 amount, address receiver) public virtual override callThroughEVC use(MODULE_VAULT) returns (uint256) {}

Expand Down Expand Up @@ -122,7 +122,7 @@ contract EVault is Dispatch {

function repayWithShares(uint256 amount, address receiver) public virtual override callThroughEVC use(MODULE_BORROWING) returns (uint256 shares, uint256 debt) {}

function pullDebt(uint256 amount, address from) public virtual override callThroughEVC use(MODULE_BORROWING) returns (uint256) {}
function pullDebt(uint256 amount, address from) public virtual override callThroughEVC use(MODULE_BORROWING) {}

function flashLoan(uint256 amount, bytes calldata data) public virtual override use(MODULE_BORROWING) {}

Expand Down Expand Up @@ -151,7 +151,7 @@ contract EVault is Dispatch {

function disableController() public virtual override use(MODULE_RISKMANAGER) {}

function checkAccountStatus(address account, address[] calldata collaterals) public virtual override returns (bytes4) { return super.checkAccountStatus(account, collaterals); }
function checkAccountStatus(address account, address[] calldata collaterals) public view virtual override returns (bytes4) { return super.checkAccountStatus(account, collaterals); }

function checkVaultStatus() public virtual override returns (bytes4) { return super.checkVaultStatus(); }

Expand Down Expand Up @@ -227,8 +227,6 @@ contract EVault is Dispatch {

function setLTV(address collateral, uint16 borrowLTV, uint16 liquidationLTV, uint32 rampDuration) public virtual override use(MODULE_GOVERNANCE) {}

function clearLTV(address collateral) public virtual override use(MODULE_GOVERNANCE) {}

function setMaxLiquidationDiscount(uint16 newDiscount) public virtual override use(MODULE_GOVERNANCE) {}

function setLiquidationCoolOffTime(uint16 newCoolOffTime) public virtual override use(MODULE_GOVERNANCE) {}
Expand Down
33 changes: 20 additions & 13 deletions src/EVault/IEVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,16 @@ interface IBorrowing {
/// @return shares Amount of shares burned
/// @return debt Amount of debt removed in assets
/// @dev Equivalent to withdrawing and repaying, but no assets are needed to be present in the vault
/// @dev Contrary to a regular `repay`, if account is unhealthy, the repay amount must bring the account back to
/// health, or the operation will revert during account status check
function repayWithShares(uint256 amount, address receiver) external returns (uint256 shares, uint256 debt);

/// @notice Take over debt from another account
/// @param amount Amount of debt in asset units (use max uint256 for all the account's debt)
/// @param from Account to pull the debt from
/// @return Amount of debt pulled in asset units.
function pullDebt(uint256 amount, address from) external returns (uint256);
/// @dev Due to internal debt precision accounting, the liability reported on either or both accounts after
/// calling `pullDebt` may not match the `amount` requested precisely
function pullDebt(uint256 amount, address from) external;

/// @notice Request a flash-loan. A onFlashLoan() callback in msg.sender will be invoked, which must repay the loan
/// to the main Euler address prior to returning.
Expand Down Expand Up @@ -284,9 +287,11 @@ interface ILiquidation {
/// @param violator Address that may be in collateral violation
/// @param collateral Collateral which is to be seized
/// @param repayAssets The amount of underlying debt to be transferred from violator to sender, in asset units (use
/// max uint256 to repay the maximum possible amount).
/// max uint256 to repay the maximum possible amount). Meant as slippage check together with `minYieldBalance`
/// @param minYieldBalance The minimum acceptable amount of collateral to be transferred from violator to sender, in
/// collateral balance units (shares for vaults)
/// collateral balance units (shares for vaults). Meant as slippage check together with `repayAssets`
/// @dev If `repayAssets` is set to max uint256 it is assumed the caller will perform their own slippage checks to
/// make sure they are not taking on too much debt. This option is mainly meant for smart contract liquidators
function liquidate(address violator, address collateral, uint256 repayAssets, uint256 minYieldBalance) external;
}

Expand Down Expand Up @@ -325,7 +330,7 @@ interface IRiskManager is IEVCVault {
/// @return magicValue Must return the bytes4 magic value 0xb168c58f (which is a selector of this function) when
/// account status is valid, or revert otherwise.
/// @dev Only callable by EVC during status checks
function checkAccountStatus(address account, address[] calldata collaterals) external returns (bytes4);
function checkAccountStatus(address account, address[] calldata collaterals) external view returns (bytes4);

/// @notice Checks the status of the vault and reverts if caps are exceeded
/// @return magicValue Must return the bytes4 magic value 0x4b3d1223 (which is a selector of this function) when
Expand Down Expand Up @@ -381,7 +386,7 @@ interface IGovernance {
function protocolConfigAddress() external view returns (address);

/// @notice Retrieves the protocol fee share
/// @return A percentage share of fees accrued belonging to the protocol. In wad scale (1e18)
/// @return A percentage share of fees accrued belonging to the protocol, in 1e4 scale
function protocolFeeShare() external view returns (uint256);

/// @notice Retrieves the address which will receive protocol's fees
Expand Down Expand Up @@ -431,6 +436,9 @@ interface IGovernance {

/// @notice Retrieves the maximum liquidation discount
/// @return The maximum liquidation discount in 1e4 scale
/// @dev The default value, which is zero, is deliberately bad, as it means there would be no incentive to liquidate
/// unhealthy users. The vault creator must take care to properly select the limit, given the underlying and
/// collaterals used.
function maxLiquidationDiscount() external view returns (uint16);

/// @notice Retrieves liquidation cool-off time, which must elapse after successful account status check before
Expand Down Expand Up @@ -483,11 +491,6 @@ interface IGovernance {
/// @param rampDuration Ramp duration in seconds
function setLTV(address collateral, uint16 borrowLTV, uint16 liquidationLTV, uint32 rampDuration) external;

/// @notice Completely clears LTV configuratrion, signalling the collateral is not considered safe to liquidate
/// anymore
/// @param collateral Address of the collateral
function clearLTV(address collateral) external;

/// @notice Set a new maximum liquidation discount
/// @param newDiscount New maximum liquidation discount in 1e4 scale
/// @dev If the discount is zero (the default), the liquidators will not be incentivized to liquidate unhealthy
Expand All @@ -503,12 +506,16 @@ interface IGovernance {

/// @notice Set a new interest rate model contract
/// @param newModel The new IRM address
/// @dev If the new model reverts, perhaps due to governor error, the vault will silently use a zero interest
/// rate. Governor should make sure the new interest rates are computed as expected.
function setInterestRateModel(address newModel) external;

/// @notice Set a new hook target and a new bitmap indicating which operations should call the hook target.
/// Operations are defined in Constants.sol
/// @param newHookTarget The new hook target address
/// Operations are defined in Constants.sol.
/// @param newHookTarget The new hook target address. Use address(0) to simply disable hooked operations
/// @param newHookedOps Bitmask with the new hooked operations
/// @dev All operations are initially disabled in a newly created vault. The vault creator must set their
/// own configuration to make the vault usable
function setHookConfig(address newHookTarget, uint32 newHookedOps) external;

/// @notice Set new bitmap indicating which config flags should be enabled. Flags are defined in Constants.sol
Expand Down
6 changes: 2 additions & 4 deletions src/EVault/modules/Borrowing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,17 @@ abstract contract BorrowingModule is IBorrowing, AssetTransfers, BalanceUtils, L
}

/// @inheritdoc IBorrowing
function pullDebt(uint256 amount, address from) public virtual nonReentrant returns (uint256) {
function pullDebt(uint256 amount, address from) public virtual nonReentrant {
(VaultCache memory vaultCache, address account) = initOperation(OP_PULL_DEBT, CHECKACCOUNT_CALLER);

if (from == account) revert E_SelfTransfer();

Assets assets = amount == type(uint256).max ? getCurrentOwed(vaultCache, from).toAssetsUp() : amount.toAssets();

if (assets.isZero()) return 0;
if (assets.isZero()) return;
transferBorrow(vaultCache, from, account, assets);

emit PullDebt(from, account, assets.toUint());

return assets.toUint();
}

/// @inheritdoc IBorrowing
Expand Down
56 changes: 30 additions & 26 deletions src/EVault/modules/Governance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ abstract contract GovernanceModule is IGovernance, BalanceUtils, BorrowUtils, LT
uint16 liquidationLTV,
uint16 initialLiquidationLTV,
uint48 targetTimestamp,
uint32 rampDuration,
bool initialized
uint32 rampDuration
);

/// @notice Set an interest rate model contract address
/// @param newInterestRateModel Address of the new IRM
event GovSetInterestRateModel(address newInterestRateModel);
Expand Down Expand Up @@ -122,7 +122,11 @@ abstract contract GovernanceModule is IGovernance, BalanceUtils, BorrowUtils, LT

/// @inheritdoc IGovernance
function protocolFeeShare() public view virtual reentrantOK returns (uint256) {
if (vaultStorage.feeReceiver == address(0)) return CONFIG_SCALE;

(, uint256 protocolShare) = protocolConfig.protocolFeeConfig(address(this));
if (protocolShare > MAX_PROTOCOL_FEE_SHARE) return MAX_PROTOCOL_FEE_SHARE;

return protocolShare;
}

Expand Down Expand Up @@ -261,16 +265,19 @@ abstract contract GovernanceModule is IGovernance, BalanceUtils, BorrowUtils, LT
}

/// @inheritdoc IGovernance
/// @dev When the collateral asset is no longer deemed suitable to sustain debt (and not because of code issues, see
/// `clearLTV`), its LTV setting can be set to 0. Setting a zero liquidation LTV also enforces a zero borrowing LTV
/// (`newBorrowLTV <= newLiquidationLTV`). In such cases, the collateral becomes immediately ineffective for new
/// borrows. However, for liquidation purposes, the LTV can be ramped down over a period of time (`rampDuration`).
/// This ramping helps users avoid hard liquidations with maximum discounts and gives them a chance to close their
/// positions in an orderly fashion. The choice of `rampDuration` depends on market conditions assessed by the
/// governor. They may decide to forgo the ramp entirely by setting the duration to zero, presumably in light of
/// extreme market conditions, where ramping would pose a threat to the vault's solvency. In any case, when the
/// liquidation LTV reaches its target of 0, this asset will no longer support the debt, but it will still be
/// possible to liquidate it at a discount and use the proceeds to repay an unhealthy loan.
/// @dev When the collateral asset is no longer deemed suitable to sustain debt, its LTV setting can be set to 0.
/// Setting a zero liquidation LTV also enforces a zero borrowing LTV (`newBorrowLTV <= newLiquidationLTV`).
/// In such cases, the collateral becomes immediately ineffective for new borrows. However, for liquidation
/// purposes, the LTV can be ramped down over a period of time (`rampDuration`). This ramping helps users avoid hard
/// liquidations with maximum discounts and gives them a chance to close their positions in an orderly fashion.
/// The choice of `rampDuration` depends on market conditions assessed by the governor. They may decide to forgo
/// the ramp entirely by setting the duration to zero, presumably in light of extreme market conditions, where
/// ramping would pose a threat to the vault's solvency. In any case, when the liquidation LTV reaches its target
/// of 0, this asset will no longer support the debt, but it will still be possible to liquidate it at a discount
/// and use the proceeds to repay an unhealthy loan.
/// Setting the LTV to zero will not be sufficient if the collateral is found to be unsafe to call liquidation on,
/// either due to a bug or a code upgrade that allows its transfer function to make arbitrary external calls.
/// In such cases, pausing the vault and conducting an orderly wind-down is recommended.
function setLTV(address collateral, uint16 borrowLTV, uint16 liquidationLTV, uint32 rampDuration)
public
virtual
Expand All @@ -295,32 +302,29 @@ abstract contract GovernanceModule is IGovernance, BalanceUtils, BorrowUtils, LT

vaultStorage.ltvLookup[collateral] = newLTV;

if (!currentLTV.initialized) vaultStorage.ltvList.push(collateral);
if (!currentLTV.isRecognizedCollateral()) vaultStorage.ltvList.push(collateral);

if (!newLiquidationLTV.isZero()) {
// Ensure that this collateral can be priced by the configured oracle
(, IPriceOracle _oracle, address _unitOfAccount) = ProxyUtils.metadata();
_oracle.getQuote(1e18, collateral, _unitOfAccount);
}

emit GovSetLTV(
collateral,
newLTV.borrowLTV.toUint16(),
newLTV.liquidationLTV.toUint16(),
newLTV.initialLiquidationLTV.toUint16(),
newLTV.targetTimestamp,
newLTV.rampDuration,
!currentLTV.initialized
newLTV.rampDuration
);
}

/// @inheritdoc IGovernance
/// @dev When LTV configuration is cleared, attempt to liquidate the collateral will revert.
/// Clearing should only be executed when the collateral is found to be unsafe to liquidate,
/// because e.g. it does external calls on transfer, which would be a critical security threat.
function clearLTV(address collateral) public virtual nonReentrant governorOnly {
uint16 originalLTV = getLTV(collateral, true).toUint16();
vaultStorage.ltvLookup[collateral].clear();

emit GovSetLTV(collateral, 0, 0, originalLTV, 0, 0, false);
}

/// @inheritdoc IGovernance
function setMaxLiquidationDiscount(uint16 newDiscount) public virtual nonReentrant governorOnly {
// Discount equal 1e4 would cause division by zero error during liquidation
if (newDiscount == CONFIG_SCALE) revert E_BadMaxLiquidationDiscount();

vaultStorage.maxLiquidationDiscount = newDiscount.toConfigAmount();
emit GovSetMaxLiquidationDiscount(newDiscount);
}
Expand Down
3 changes: 2 additions & 1 deletion src/EVault/modules/Initialize.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ abstract contract InitializeModule is IInitialize, BorrowUtils {
(IERC20 asset,,) = ProxyUtils.metadata();
// Make sure the asset is a contract. Token transfers using a library will not revert if address has no code.
AddressUtils.checkContract(address(asset));
// Other constraints on values should be enforced by product line

// Create sidecar DToken

Expand All @@ -49,6 +48,8 @@ abstract contract InitializeModule is IInitialize, BorrowUtils {
vaultStorage.interestAccumulator = INITIAL_INTEREST_ACCUMULATOR;
vaultStorage.interestFee = DEFAULT_INTEREST_FEE.toConfigAmount();
vaultStorage.creator = vaultStorage.governorAdmin = proxyCreator;
// all operations are initially disabled
vaultStorage.hookedOps = Flags.wrap(OP_MAX_VALUE - 1);

{
string memory underlyingSymbol = getTokenSymbol(address(asset));
Expand Down
Loading
Loading