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

add october 17th, 2024 spell and tests #55

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
BASE_RPC_URL: ${{secrets.BASE_RPC_URL}}
GOERLI_RPC_URL: ${{secrets.GOERLI_RPC_URL}}
run: |
forge test -vvv
forge test -vvv --evm-version cancun
Copy link
Collaborator Author

@0xShaito 0xShaito Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag was added based on this open issue in foundry.

We can remove it but we would need to remove the tests for the price of the pt token oracles.

id: test

# submits a PR comment with a spell simulation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
## Reserve changes

### Reserves added

#### sUSDS ([0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD](https://etherscan.io/address/0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD))

| description | value |
| --- | --- |
| decimals | 18 |
| isActive | true |
| isFrozen | false |
| supplyCap | 50,000,000 sUSDS |
| borrowCap | 0 sUSDS |
| debtCeiling | 0 $ |
| isSiloed | false |
| isFlashloanable | false |
| eModeCategory | 0 |
| oracle | [0x27f3A665c75aFdf43CfbF6B3A859B698f46ef656](https://etherscan.io/address/0x27f3A665c75aFdf43CfbF6B3A859B698f46ef656) |
| oracleLatestAnswer | 100,362,036 |
| usageAsCollateralEnabled | true |
| ltv | 79 % |
| liquidationThreshold | 80 % |
| liquidationBonus | 5 % |
| liquidationProtocolFee | 10 % |
| reserveFactor | 10 % |
| aToken | [0x6715bc100A183cc65502F05845b589c1919ca3d3](https://etherscan.io/address/0x6715bc100A183cc65502F05845b589c1919ca3d3) |
| aTokenImpl | [0x6175ddEc3B9b38c88157C10A01ed4A3fa8639cC6](https://etherscan.io/address/0x6175ddEc3B9b38c88157C10A01ed4A3fa8639cC6) |
| variableDebtToken | [0x4e89b83f426fED3f2EF7Bb2d7eb5b53e288e1A13](https://etherscan.io/address/0x4e89b83f426fED3f2EF7Bb2d7eb5b53e288e1A13) |
| variableDebtTokenImpl | [0x86C71796CcDB31c3997F8Ec5C2E3dB3e9e40b985](https://etherscan.io/address/0x86C71796CcDB31c3997F8Ec5C2E3dB3e9e40b985) |
| stableDebtToken | [0x55580770e14E008082aB2E8d08a16Cc1dC192741](https://etherscan.io/address/0x55580770e14E008082aB2E8d08a16Cc1dC192741) |
| stableDebtTokenImpl | [0x026a5B6114431d8F3eF2fA0E1B2EDdDccA9c540E](https://etherscan.io/address/0x026a5B6114431d8F3eF2fA0E1B2EDdDccA9c540E) |
| borrowingEnabled | false |
| stableBorrowRateEnabled | false |
| isBorrowableInIsolation | false |
| interestRateStrategy | [0xa8632b2f0A3C5327a77ee51a47A168B6490A7178](https://etherscan.io/address/0xa8632b2f0A3C5327a77ee51a47A168B6490A7178) |
| aTokenName | Spark sUSDS |
| aTokenSymbol | spsUSDS |
| borrowCapGap | 0 |
| borrowCapIncreaseCooldown | 0 |
| isPaused | false |
| maxBorrowCap | 0 |
| maxSupplyCap | 500,000,000 |
| stableDebtTokenName | Spark Stable Debt sUSDS |
| stableDebtTokenSymbol | stableDebtsUSDS |
| supplyCapGap | 50,000,000 |
| supplyCapIncreaseCooldown | 43,200 |
| variableDebtTokenName | Spark Variable Debt sUSDS |
| variableDebtTokenSymbol | variableDebtsUSDS |
| optimalUsageRatio | 80 % |
| maxExcessUsageRatio | 20 % |
| baseVariableBorrowRate | 0 % |
| variableRateSlope1 | 2 % |
| variableRateSlope2 | 300 % |
| baseStableBorrowRate | 2 % |
| stableRateSlope1 | 0 % |
| stableRateSlope2 | 0 % |
| optimalStableToTotalDebtRatio | 0 % |
| maxExcessStableToTotalDebtRatio | 100 % |


### Reserve altered

#### WBTC ([0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599](https://etherscan.io/address/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599))

| description | value before | value after |
| --- | --- | --- |
| liquidationThreshold | 75 % | 70 % |
| liquidationProtocolFee | 10 % | 0 % |
| borrowCapGap | 100 | 1 |
| maxBorrowCap | 2,000 | 1 |
| maxSupplyCap | 10,000 | 5,000 |
| supplyCapGap | 500 | 200 |


#### sDAI ([0x83F20F44975D03b1b09e64809B757c47f942BEeA](https://etherscan.io/address/0x83F20F44975D03b1b09e64809B757c47f942BEeA))

| description | value before | value after |
| --- | --- | --- |
| oracle | [0xb9E6DBFa4De19CCed908BcbFe1d015190678AB5f](https://etherscan.io/address/0xb9E6DBFa4De19CCed908BcbFe1d015190678AB5f) | [0x0c0864837C7e65458aCD3C665222203217019436](https://etherscan.io/address/0x0c0864837C7e65458aCD3C665222203217019436) |
| oracleLatestAnswer | 111,215,106 | 111,239,740 |


## Raw diff

```json
{
"reserves": {
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": {
"borrowCapGap": {
"from": 100,
"to": 1
},
"liquidationProtocolFee": {
"from": 1000,
"to": 0
},
"liquidationThreshold": {
"from": 7500,
"to": 7000
},
"maxBorrowCap": {
"from": 2000,
"to": 1
},
"maxSupplyCap": {
"from": 10000,
"to": 5000
},
"supplyCapGap": {
"from": 500,
"to": 200
}
},
"0x83F20F44975D03b1b09e64809B757c47f942BEeA": {
"oracle": {
"from": "0xb9E6DBFa4De19CCed908BcbFe1d015190678AB5f",
"to": "0x0c0864837C7e65458aCD3C665222203217019436"
},
"oracleLatestAnswer": {
"from": 111215106,
"to": 111239740
}
},
"0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD": {
"from": null,
"to": {
"aToken": "0x6715bc100A183cc65502F05845b589c1919ca3d3",
"aTokenImpl": "0x6175ddEc3B9b38c88157C10A01ed4A3fa8639cC6",
"aTokenName": "Spark sUSDS",
"aTokenSymbol": "spsUSDS",
"borrowCap": 0,
"borrowCapGap": 0,
"borrowCapIncreaseCooldown": 0,
"borrowingEnabled": false,
"debtCeiling": 0,
"decimals": 18,
"eModeCategory": 0,
"interestRateStrategy": "0xa8632b2f0A3C5327a77ee51a47A168B6490A7178",
"isActive": true,
"isBorrowableInIsolation": false,
"isFlashloanable": false,
"isFrozen": false,
"isPaused": false,
"isSiloed": false,
"liquidationBonus": 10500,
"liquidationProtocolFee": 1000,
"liquidationThreshold": 8000,
"ltv": 7900,
"maxBorrowCap": 0,
"maxSupplyCap": 500000000,
"oracle": "0x27f3A665c75aFdf43CfbF6B3A859B698f46ef656",
"oracleLatestAnswer": 100362036,
"reserveFactor": 1000,
"stableBorrowRateEnabled": false,
"stableDebtToken": "0x55580770e14E008082aB2E8d08a16Cc1dC192741",
"stableDebtTokenImpl": "0x026a5B6114431d8F3eF2fA0E1B2EDdDccA9c540E",
"stableDebtTokenName": "Spark Stable Debt sUSDS",
"stableDebtTokenSymbol": "stableDebtsUSDS",
"supplyCap": 50000000,
"supplyCapGap": 50000000,
"supplyCapIncreaseCooldown": 43200,
"symbol": "sUSDS",
"underlying": "0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD",
"usageAsCollateralEnabled": true,
"variableDebtToken": "0x4e89b83f426fED3f2EF7Bb2d7eb5b53e288e1A13",
"variableDebtTokenImpl": "0x86C71796CcDB31c3997F8Ec5C2E3dB3e9e40b985",
"variableDebtTokenName": "Spark Variable Debt sUSDS",
"variableDebtTokenSymbol": "variableDebtsUSDS"
}
}
},
"strategies": {
"0xa8632b2f0A3C5327a77ee51a47A168B6490A7178": {
"from": null,
"to": {
"baseStableBorrowRate": "20000000000000000000000000",
"baseVariableBorrowRate": "0",
"maxExcessStableToTotalDebtRatio": "1000000000000000000000000000",
"maxExcessUsageRatio": "200000000000000000000000000",
"optimalStableToTotalDebtRatio": "0",
"optimalUsageRatio": "800000000000000000000000000",
"stableRateSlope1": "0",
"stableRateSlope2": "0",
"variableRateSlope1": "20000000000000000000000000",
"variableRateSlope2": "3000000000000000000000000000"
}
}
}
}
```
160 changes: 160 additions & 0 deletions src/proposals/20241017/SparkEthereum_20241017.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.10;

import { IERC20 } from "forge-std/interfaces/IERC20.sol";

import { Ethereum, SparkPayloadEthereum, IEngine, Rates, EngineFlags } from 'src/SparkPayloadEthereum.sol';

import { ICapAutomator } from "lib/sparklend-cap-automator/src/interfaces/ICapAutomator.sol";

import { IMetaMorpho, MarketParams } from 'lib/metamorpho/src/interfaces/IMetaMorpho.sol';

/**
* @title Oct 17, 2024 Spark Ethereum Proposal
* @notice onboard sUSDS
* Update Oracle for sDAI
* Onboard Pendle sUSDe PTs to Morpho Spark DAI Vault
* WBTC Changes
* @author Phoenix Labs
* Forum: https://forum.sky.money/t/oct-3-2024-proposed-changes-to-spark-for-upcoming-spell/25293
* Vote: https://vote.makerdao.com/polling/QmbHaA2G
* https://vote.makerdao.com/polling/QmShWccA
* https://vote.makerdao.com/polling/QmTksxrr
* https://vote.makerdao.com/polling/QmSiQVWm
*/
contract SparkEthereum_20241017 is SparkPayloadEthereum {

address internal constant SUSDS = 0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD;
address internal constant SUSDS_PRICE_FEED = 0x27f3A665c75aFdf43CfbF6B3A859B698f46ef656;
0xteddybear marked this conversation as resolved.
Show resolved Hide resolved

address internal constant SDAI_PRICE_FEED = 0x0c0864837C7e65458aCD3C665222203217019436;
0xteddybear marked this conversation as resolved.
Show resolved Hide resolved

address internal constant PT_SUSDE_26DEC2024 = 0xEe9085fC268F6727d5D4293dBABccF901ffDCC29;
address internal constant PT_26DEC2024_PRICE_FEED = 0x81E5E28F33D314e9211885d6f0F4080E755e4595;

address internal constant PT_SUSDE_27MAR2025 = 0xE00bd3Df25fb187d6ABBB620b3dfd19839947b81;
address internal constant PT_27MAR2025_PRICE_FEED = 0x38d130cEe60CDa080A3b3aC94C79c34B6Fc919A7;

function newListings()
public pure override returns (IEngine.Listing[] memory)
{
IEngine.Listing[] memory listings = new IEngine.Listing[](1);

listings[0] = IEngine.Listing({
asset: SUSDS,
assetSymbol: 'sUSDS',
priceFeed: SUSDS_PRICE_FEED,
rateStrategyParams: Rates.RateStrategyParams({
optimalUsageRatio: _bpsToRay(80_00),
baseVariableBorrowRate: 0,
variableRateSlope1: _bpsToRay(2_00),
variableRateSlope2: _bpsToRay(300_00),
stableRateSlope1: 0,
stableRateSlope2: 0,
baseStableRateOffset: 0,
stableRateExcessOffset: 0,
optimalStableToTotalDebtRatio: 0
}),
enabledToBorrow: EngineFlags.DISABLED,
stableRateModeEnabled: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.DISABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.DISABLED,
ltv: 79_00,
liqThreshold: 80_00,
liqBonus: 5_00,
reserveFactor: 10_00,
supplyCap: 50_000_000,
borrowCap: 0,
debtCeiling: 0,
liqProtocolFee: 10_00,
eModeCategory: 0
});

return listings;
}

function priceFeedsUpdates() public pure override returns (IEngine.PriceFeedUpdate[] memory) {
IEngine.PriceFeedUpdate[] memory updates = new IEngine.PriceFeedUpdate[](1);

updates[0] = IEngine.PriceFeedUpdate({
asset: Ethereum.SDAI,
priceFeed: SDAI_PRICE_FEED
});

return updates;
}

function collateralsUpdates() public pure override returns (IEngine.CollateralUpdate[] memory) {
// Reduce LT from 75% to 70%
// Reduce liquidation protocol fee from 10% to 0%
IEngine.CollateralUpdate[] memory updates = new IEngine.CollateralUpdate[](1);
updates[0] = IEngine.CollateralUpdate({
asset: Ethereum.WBTC,
ltv: EngineFlags.KEEP_CURRENT,
liqThreshold: 70_00,
liqBonus: EngineFlags.KEEP_CURRENT,
debtCeiling: EngineFlags.KEEP_CURRENT,
liqProtocolFee: 0,
eModeCategory: EngineFlags.KEEP_CURRENT
});
return updates;
}

function _postExecute() internal override {
ICapAutomator capAutomator = ICapAutomator(Ethereum.CAP_AUTOMATOR);

// sUSDS onboarding
capAutomator.setSupplyCapConfig({
asset: SUSDS,
max: 500_000_000,
gap: 50_000_000,
increaseCooldown: 12 hours
});

// Making an initial deposit right after the listing to prevent spToken value manipulation
IERC20(SUSDS).approve(address(LISTING_ENGINE.POOL()), 1e6);
LISTING_ENGINE.POOL().deposit(SUSDS, 1e6, address(this), 0);
lucas-manuel marked this conversation as resolved.
Show resolved Hide resolved

// Onboard Pendle sUSDe PTs to Morpho Spark DAI Vault
IMetaMorpho(Ethereum.MORPHO_VAULT_DAI_1).submitCap(
MarketParams({
loanToken: Ethereum.DAI,
collateralToken: PT_SUSDE_26DEC2024,
oracle: PT_26DEC2024_PRICE_FEED,
irm: Ethereum.MORPHO_DEFAULT_IRM,
lltv: 0.915e18
}),
100_000_000e18
);

IMetaMorpho(Ethereum.MORPHO_VAULT_DAI_1).submitCap(
MarketParams({
loanToken: Ethereum.DAI,
collateralToken: PT_SUSDE_27MAR2025,
oracle: PT_27MAR2025_PRICE_FEED,
irm: Ethereum.MORPHO_DEFAULT_IRM,
lltv: 0.915e18
}),
100_000_000e18
);

// Reduce supply cap max from 10,000 WBTC to 5,000 WBTC
// Reduce supply cap gap from 500 WBTC to 200 WBTC
capAutomator.setSupplyCapConfig({
asset: Ethereum.WBTC,
max: 5_000,
gap: 200,
increaseCooldown: 12 hours
});

// Reduce borrow cap max from 2,000 WBTC to 1 WBTC
// Reduce borrow cap gap from 100 WBTC to 1 WBTC
capAutomator.setBorrowCapConfig({
asset: Ethereum.WBTC,
max: 1,
gap: 1,
increaseCooldown: 12 hours
});
}
}
Loading
Loading