Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
amusingaxl committed Nov 25, 2024
1 parent 85359a3 commit 229237c
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 52 deletions.
176 changes: 157 additions & 19 deletions src/DssSpell.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,30 @@ pragma solidity 0.8.16;

import "dss-exec-lib/DssExec.sol";
import "dss-exec-lib/DssAction.sol";
import { VestAbstract } from "dss-interfaces/dss/VestAbstract.sol";
import { GemAbstract } from "dss-interfaces/ERC/GemAbstract.sol";
import { JugAbstract } from "dss-interfaces/dss/JugAbstract.sol";

interface RwaLiquidationOracleLike {
function cull(bytes32 ilk, address urn) external;
}
import {GemAbstract} from "dss-interfaces/ERC/GemAbstract.sol";

interface ProxyLike {
function exec(address target, bytes calldata args) external payable returns (bytes memory out);
}

interface SUsdsLike {
function file(bytes32, uint256) external;
function drip() external returns (uint256);
interface PauseLike {
function setDelay(uint256) external;
}

interface DaiUsdsLike {
function daiToUsds(address usr, uint256 wad) external;
}

interface MkrSkyLike {
function mkrToSky(address usr, uint256 wad) external;
function rate() external view returns (uint256);
}

contract DssSpellAction is DssAction {
// Provides a descriptive tag for bot consumption
// This should be modified weekly to provide a summary of the actions
// Hash: cast keccak -- "$(wget 'https://raw.githubusercontent.com/makerdao/community/aa58678ff632f8e25047a345709cd3c9f1819e4f/governance/votes/Executive%20vote%20-%20November%2014%2C%202024.md' -q -O - 2>/dev/null)"
string public constant override description =
"2024-11-28 MakerDAO Executive Spell | Hash: TODO";
string public constant override description = "2024-11-28 MakerDAO Executive Spell | Hash: TODO";

// Set office hours according to the summary
function officeHours() public pure override returns (bool) {
Expand All @@ -64,26 +61,167 @@ contract DssSpellAction is DssAction {
// uint256 internal constant X_PCT_RATE = ;

// ---------- Math ----------

// ---------- Contracts ----------
uint256 internal constant THOUSAND = 10 ** 3;
uint256 internal constant MILLION = 10 ** 6;
uint256 internal constant WAD = 10 ** 18;

// ---------- MCD Addresses ----------
GemAbstract internal immutable MKR = GemAbstract(DssExecLib.mkr());
GemAbstract internal immutable DAI = GemAbstract(DssExecLib.dai());
address internal immutable MCD_PAUSE = DssExecLib.getChangelogAddress("MCD_PAUSE");
address internal immutable DAI_USDS = DssExecLib.getChangelogAddress("DAI_USDS");
address internal immutable MKR_SKY = DssExecLib.getChangelogAddress("MKR_SKY");
uint256 internal immutable MKR_SKY_RATE = MkrSkyLike(DssExecLib.getChangelogAddress("MKR_SKY")).rate();
address internal immutable MCD_ESM = DssExecLib.getChangelogAddress("MCD_ESM");

// ---------- Wallets ----------

// ---------- Timestamps ----------
address internal constant LAUNCH_PROJECT_FUNDING = 0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F;
address internal constant LIQUIDITY_BOOTSTRAPPING = 0xD8507ef0A59f37d15B5D7b630FA6EEa40CE4AFdD;
address internal constant INTEGRATION_BOOST_INITIATIVE = 0xD6891d1DFFDA6B0B1aF3524018a1eE2E608785F7;
address internal constant BLUE = 0xb6C09680D822F162449cdFB8248a7D3FC26Ec9Bf;
address internal constant BONAPUBLICA = 0x167c1a762B08D7e78dbF8f24e5C3f1Ab415021D3;
address internal constant BYTERON = 0xc2982e72D060cab2387Dba96b846acb8c96EfF66;
address internal constant CLOAKY = 0x869b6d5d8FA7f4FFdaCA4D23FFE0735c5eD1F818;
address internal constant JULIACHANG = 0x252abAEe2F4f4b8D39E5F12b163eDFb7fac7AED7;
address internal constant VIGILANT = 0x2474937cB55500601BCCE9f4cb0A0A72Dc226F61;
address internal constant CLOAKY_KOHLA_2 = 0x73dFC091Ad77c03F2809204fCF03C0b9dccf8c7a;
address internal constant CLOAKY_ENNOIA = 0xA7364a1738D0bB7D1911318Ca3FB3779A8A58D7b;

// ---------- Spark Proxy Spell ----------
// Spark Proxy: https://github.com/marsfoundation/sparklend-deployments/blob/bba4c57d54deb6a14490b897c12a949aa035a99b/script/output/1/primary-sce-latest.json#L2
address internal constant SPARK_PROXY = 0x3300f198988e4C9C63F75dF86De36421f06af8c4;
address internal constant SPARK_SPELL = address(0);
address internal constant SPARK_SPELL = 0x6c87D984689CeD0bB367A58722aC74013F82267d;

function actions() public override {
// ---------- Section ----------
// ---------- DIRECT-SPK-AAVE-LIDO-USDS DDM line increase ----------
// Forum: TODO
// Poll: TODO

// Increase DIRECT-SPK-AAVE-LIDO-USDS DDM line by 100 million, USDS from 100 million USDS to 200 million USDS
DssExecLib.setIlkAutoLineDebtCeiling("DIRECT-SPK-AAVE-LIDO-USDS", 200 * MILLION);

// ---------- Surplus Buffer Upper Limit increase ----------
// Forum: TODO
// Poll: TODO

// Increase the Surplus Buffer Upper Limit by 60 million DAI, from 60 million DAI to 120 million DAI
DssExecLib.setSurplusBuffer(120 * MILLION);

// ---------- Add emergency spells to the chainlog ----------
// Forum: TODO
// Poll: TODO

// TBC

// ---------- Rate Changes ----------
// Forum: TODO
// Poll: TODO

// TBC

// ---------- GSM Delay increase ----------
// Forum: TODO
// Poll: TODO

// Increase GSM Delay by 14 hours, from 16 hours to 30 hours
PauseLike(MCD_PAUSE).setDelay(30 hours);

// ---------- Launch Project Funding ----------
// Forum: TODO
// Poll: TODO

// Transfer 10,000,000 USDS to 0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F
_transferUsds(LAUNCH_PROJECT_FUNDING, 10 * MILLION * WAD);

// Transfer 24,000,000 SKY to 0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F
_transferSky(LAUNCH_PROJECT_FUNDING, 24 * MILLION * WAD);

// ---------- Sky Ecosystem Liquidity Bootstrapping Funding ----------
// Forum: TODO
// Poll: TODO

// Transfer 6,000,000 USDS to 0xD8507ef0A59f37d15B5D7b630FA6EEa40CE4AFdD
_transferUsds(LIQUIDITY_BOOTSTRAPPING, 6 * MILLION * WAD);

// ---------- Integration Boost Funding ----------
// Forum: TODO
// Poll: TODO

// Execute Spark Proxy Spell at 0x8a3aaeAC45Cf3D76Cf82b0e4C63cCfa8c72BDCa7
// Transfer 3,000,000 USDS to 0xD6891d1DFFDA6B0B1aF3524018a1eE2E608785F7
_transferUsds(INTEGRATION_BOOST_INITIATIVE, 3 * MILLION * WAD);

// ---------- ESM Minimum Threshold increase ----------
// Forum: TODO
// Poll: TODO

// Increase ESM Minimum Threshold by 200,000 MKR, from 300,000 MKR to 500,000 MKR
DssExecLib.setValue(MCD_ESM, "min", 500 * THOUSAND * WAD);

// ---------- October 2024 AD Compensation ----------
// Forum: TODO
// Poll: TODO

// BLUE - 2,968 USDS - 0xb6C09680D822F162449cdFB8248a7D3FC26Ec9Bf
_transferUsds(BLUE, 2_968 * WAD);
// Bonapublica - 4,000 USDS - 0x167c1a762B08D7e78dbF8f24e5C3f1Ab415021D3
_transferUsds(BONAPUBLICA, 4_000 * WAD);
// Byteron - 1,733 USDS - 0xc2982e72D060cab2387Dba96b846acb8c96EfF66
_transferUsds(BYTERON, 1_733 * WAD);
// Cloaky - 4,000 USDS - 0x869b6d5d8FA7f4FFdaCA4D23FFE0735c5eD1F818
_transferUsds(CLOAKY, 4_000 * WAD);
// JuliaChang - 4,000 USDS - 0x252abAEe2F4f4b8D39E5F12b163eDFb7fac7AED7
_transferUsds(JULIACHANG, 4_000 * WAD);
// vigilant - 4,000 USDS - 0x2474937cB55500601BCCE9f4cb0A0A72Dc226F61
_transferUsds(VIGILANT, 4_000 * WAD);

// ---------- Atlas Core Development Payments ----------
// Forum: TODO
// Poll: TODO

// Kohla (Cloaky) - 20,000 USDS - 0x73dFC091Ad77c03F2809204fCF03C0b9dccf8c7a
_transferUsds(CLOAKY_KOHLA_2, 20_000 * WAD);
// Ennoia (Cloaky) - 20,110 USDS - 0xA7364a1738D0bB7D1911318Ca3FB3779A8A58D7b
_transferUsds(CLOAKY_ENNOIA, 20_110 * WAD);
// BLUE - 50,167 USDS - 0xb6C09680D822F162449cdFB8248a7D3FC26Ec9Bf
_transferUsds(BLUE, 50_167 * WAD);
// BLUE - 330,000 SKY - 0xb6C09680D822F162449cdFB8248a7D3FC26Ec9Bf
_transferSky(BLUE, 330_000 * WAD);

// ---------- Spark Proxy Spell ----------
// Forum: TODO
// Poll: TODO

// Execute Spark Proxy Spell at 0x6c87D984689CeD0bB367A58722aC74013F82267d
// ProxyLike(SPARK_PROXY).exec(SPARK_SPELL, abi.encodeWithSignature("execute()"));
}

/// @notice wraps the operations required to transfer USDS from the surplus buffer
/// @param usr The USDS receiver.
/// @param wad The USDS amount in wad precision (10**18)
function _transferUsds(address usr, uint256 wad) internal {
// Note: Enforce whole units to avoid rounding errors
require(wad % WAD == 0, "transferUsds/non-integer-wad");
// Note: DssExecLib currently only supports Dai transfers from the surplus buffer.
DssExecLib.sendPaymentFromSurplusBuffer(address(this), wad / WAD);
// Note: Approve DAI_USDS for the amount sent to be able to convert it.
DAI.approve(DAI_USDS, wad);
// Transfer 3,000,000 USDS to 0xD6891d1DFFDA6B0B1aF3524018a1eE2E608785F7
DaiUsdsLike(DAI_USDS).daiToUsds(usr, wad);
}

/// @notice wraps the operations required to transfer SKY from the surplus buffer
/// @param usr The SKY receiver.
/// @param wad The SKY amount in wad precision (10**18).
function _transferSky(address usr, uint256 wad) internal {
// Note: Enforce exact conversion to avoid rounding errors
require(wad % MKR_SKY_RATE == 0, "transferSky/non-exact-conversion");
// Note: Calculate the amount of MKR required
uint256 mkrWad = wad / MKR_SKY_RATE;
// Note: Approve MKR_SKY for the amount sent to be able to convert it
MKR.approve(MKR_SKY, mkrWad);
// Note: Convert the calculated amount to SKY for `usr`
MkrSkyLike(MKR_SKY).mkrToSky(usr, mkrWad);
}
}

contract DssSpell is DssExec {
Expand Down
2 changes: 1 addition & 1 deletion src/DssSpell.t.base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ contract DssSpellTestBase is Config, DssTest {
{
uint256 normalizedMin = values.esm_min * WAD;
assertEq(esm.min(), normalizedMin, "TestError/esm-min");
assertTrue(esm.min() > WAD && esm.min() < 400 * THOUSAND * WAD, "TestError/esm-min-range");
assertTrue(esm.min() > WAD && esm.min() < 600 * THOUSAND * WAD, "TestError/esm-min-range");
}

// check Pause authority
Expand Down
51 changes: 24 additions & 27 deletions src/DssSpell.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -674,39 +674,36 @@ contract DssSpellTest is DssSpellTestBase {
int256 sky;
}

function testPayments() public skipped { // add the `skipped` modifier to skip
bool ignoreTotalSupplyDaiUsds = true; // Set to false unless there is SubDAO spell interference
function testPayments() public { // add the `skipped` modifier to skip
bool ignoreTotalSupplyDaiUsds = false; // Set to false unless there is SubDAO spell interference

// For each payment, create a Payee object with:
// the address of the transferred token,
// the destination address,
// the amount to be paid
// Initialize the array with the number of payees
Payee[18] memory payees = [
Payee(address(dai), wallets.addr("JULIACHANG"), 109_168 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("CLOAKY"), 58_412 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("BLUE"), 54_167 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("BYTERON"), 34_517 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("VIGILANT"), 16_155 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("CLOAKY_KOHLA_2"), 10_000 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("CLOAKY_ENNOIA"), 10_000 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("BONAPUBLICA"), 8_333 ether), // Note: ether is only a keyword helper
Payee(address(dai), wallets.addr("ROCKY"), 7_796 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("BLUE"), 13.75 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("CLOAKY"), 29.25 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("JULIACHANG"), 28.75 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("BYTERON"), 9.68 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("VIGILANT"), 2.43 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("BONAPUBLICA"), 2.06 ether), // Note: ether is only a keyword helper
Payee(address(mkr), wallets.addr("ROCKY"), 1.17 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("LIQUIDITY_BOOTSTRAPPING"), 4_000_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("INTEGRATION_BOOST_INITIATIVE"), 3_000_000 ether) // Note: ether is only a keyword helper
Payee[13] memory payees = [
Payee(address(usds), wallets.addr("LAUNCH_PROJECT_FUNDING"), 10_000_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("LIQUIDITY_BOOTSTRAPPING"), 6_000_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("INTEGRATION_BOOST_INITIATIVE"), 3_000_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("BLUE"), 53_135 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("BONAPUBLICA"), 4_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("BYTERON"), 1_733 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("CLOAKY"), 4_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("JULIACHANG"), 4_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("VIGILANT"), 4_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("CLOAKY_KOHLA_2"), 20_000 ether), // Note: ether is only a keyword helper
Payee(address(usds), wallets.addr("CLOAKY_ENNOIA"), 20_110 ether), // Note: ether is only a keyword helper
Payee(address(sky), wallets.addr("LAUNCH_PROJECT_FUNDING"), 24_000_000 ether), // Note: ether is only a keyword helper
Payee(address(sky), wallets.addr("BLUE"), 330_000 ether) // Note: ether is only a keyword helper
];

// Fill the total values from exec sheet
PaymentAmounts memory expectedTotalDiff = PaymentAmounts({
dai: 308_548 ether, // Note: ether is only a keyword helper
mkr: 87.09 ether, // Note: ether is only a keyword helper
usds: 7_000_000 ether, // Note: ether is only a keyword helper
sky: 0 ether // Note: ether is only a keyword helper
dai: 0 ether, // Note: ether is only a keyword helper
mkr: 0 ether, // Note: ether is only a keyword helper
usds: 19_110_978 ether, // Note: ether is only a keyword helper
sky: 24_330_000 ether // Note: ether is only a keyword helper
});

// Vote, schedule and warp, but not yet cast (to get correct surplus balance)
Expand Down Expand Up @@ -1052,9 +1049,9 @@ contract DssSpellTest is DssSpellTestBase {
}

// SPARK TESTS
function testSparkSpellIsExecuted() public skipped { // add the `skipped` modifier to skip
function testSparkSpellIsExecuted() public { // add the `skipped` modifier to skip
address SPARK_PROXY = addr.addr('SPARK_PROXY');
address SPARK_SPELL = 0x8a3aaeAC45Cf3D76Cf82b0e4C63cCfa8c72BDCa7;
address SPARK_SPELL = 0x6c87D984689CeD0bB367A58722aC74013F82267d;

vm.expectCall(
SPARK_PROXY,
Expand Down
10 changes: 5 additions & 5 deletions src/test/config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,19 @@ contract Config {
afterSpell.line_offset = 680 * MILLION; // Offset between the global line against the sum of local lines
afterSpell.pot_dsr = 7_50; // In basis points
afterSpell.susds_ssr = 8_50; // In basis points
afterSpell.pause_delay = 16 hours; // In seconds
afterSpell.pause_delay = 30 hours; // In seconds
afterSpell.vow_wait = 156 hours; // In seconds
afterSpell.vow_dump = 250; // In whole Dai units
afterSpell.vow_sump = 50 * THOUSAND; // In whole Dai units
afterSpell.vow_bump = 25 * THOUSAND; // In whole Dai units
afterSpell.vow_hump_min = 60 * MILLION; // In whole Dai units
afterSpell.vow_hump_max = 60 * MILLION; // In whole Dai units
afterSpell.vow_hump_min = 120 * MILLION; // In whole Dai units
afterSpell.vow_hump_max = 120 * MILLION; // In whole Dai units
afterSpell.split_hop = 15_649 seconds; // In seconds
afterSpell.split_burn = 70_00; // In basis points
afterSpell.split_farm = "REWARDS_LSMKR_USDS"; // Farm chainlog key
afterSpell.flap_want = 9800; // In basis points
afterSpell.dog_Hole = 150 * MILLION; // In whole Dai units
afterSpell.esm_min = 300 * THOUSAND; // In whole MKR units
afterSpell.esm_min = 500 * THOUSAND; // In whole MKR units
afterSpell.pause_authority = "MCD_ADM"; // Pause authority
afterSpell.osm_mom_authority = "MCD_ADM"; // OsmMom authority
afterSpell.clipper_mom_authority = "MCD_ADM"; // ClipperMom authority
Expand Down Expand Up @@ -1551,7 +1551,7 @@ contract Config {
});
afterSpell.collaterals["DIRECT-SPK-AAVE-LIDO-USDS"] = CollateralValues({
aL_enabled: true,
aL_line: 100 * MILLION,
aL_line: 200 * MILLION,
aL_gap: 50 * MILLION,
aL_ttl: 24 hours,
line: 0,
Expand Down

0 comments on commit 229237c

Please sign in to comment.