Skip to content

Commit

Permalink
feat: add LSMKR => SPK farm scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
amusingaxl committed Oct 7, 2024
1 parent 45a533c commit d785557
Show file tree
Hide file tree
Showing 6 changed files with 426 additions and 0 deletions.
127 changes: 127 additions & 0 deletions script/dependencies/phase-1d/LsmkrSpkFarmingInit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

pragma solidity ^0.8.16;

import {StakingRewardsInit, StakingRewardsInitParams} from "../StakingRewardsInit.sol";
import {VestedRewardsDistributionInit, VestedRewardsDistributionInitParams} from "../VestedRewardsDistributionInit.sol";
import {VestInit, VestCreateParams} from "../VestInit.sol";

struct LsmkrSpkFarmingInitParams {
address lsmkr;
address spk;
address rewards;
bytes32 rewardsKey; // Chainlog key
address dist;
bytes32 distKey; // Chainlog key
address vest;
uint256 vestTot;
uint256 vestBgn;
uint256 vestTau;
}

struct LsmkrSpkFarmingInitResult {
uint256 vestId;
}

library LsmkrSpkFarmingInit {
ChainlogLike internal constant chainlog = ChainlogLike(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F);

function init(LsmkrSpkFarmingInitParams memory p) internal returns (LsmkrSpkFarmingInitResult memory r) {
require(DssVestWithGemLike(p.vest).gem() == p.spk, "LsmkrSpkFarmingInit/vest-gem-mismatch");

require(
StakingRewardsLike(p.rewards).stakingToken() == p.lsmkr,
"LsmkrSpkFarmingInit/rewards-staking-token-mismatch"
);
require(
StakingRewardsLike(p.rewards).rewardsToken() == p.spk,
"LsmkrSpkFarmingInit/rewards-rewards-token-mismatch"
);
require(StakingRewardsLike(p.rewards).rewardRate() == 0, "LsmkrSpkFarmingInit/reward-rate-not-zero");
require(
StakingRewardsLike(p.rewards).rewardsDistribution() == address(0),
"LsmkrSpkFarmingInit/rewards-distribution-already-set"
);
require(
StakingRewardsLike(p.rewards).owner() == chainlog.getAddress("MCD_PAUSE_PROXY"),
"LsmkrSpkFarmingInit/invalid-owner"
);

require(VestedRewardsDistributionLike(p.dist).gem() == p.spk, "LsmkrSpkFarmingInit/dist-gem-mismatch");
require(
VestedRewardsDistributionLike(p.dist).dssVest() == p.vest,
"LsmkrSpkFarmingInit/dist-dss-vest-mismatch"
);
require(
VestedRewardsDistributionLike(p.dist).stakingRewards() == p.rewards,
"LsmkrSpkFarmingInit/dist-staking-rewards-mismatch"
);

// `vest` is expected to be an instance of `DssVestMintable`.
// Check if minting rights on `spk` were granted to `vest`.
require(WardsLike(p.spk).wards(p.vest) == 1, "LsmkrSpkFarmingInit/missing-spk-rely-vest");
// Set `dist` with `rewardsDistribution` role in `rewards`.
StakingRewardsInit.init(p.rewards, StakingRewardsInitParams({dist: p.dist}));

// Create the proper vesting stream for rewards distribution.
uint256 vestId = VestInit.create(
p.vest,
VestCreateParams({usr: p.dist, tot: p.vestTot, bgn: p.vestBgn, tau: p.vestTau, eta: 0})
);

// Set the `vestId` in `dist`
VestedRewardsDistributionInit.init(p.dist, VestedRewardsDistributionInitParams({vestId: vestId}));

r.vestId = vestId;

chainlog.setAddress(p.rewardsKey, p.rewards);
chainlog.setAddress(p.distKey, p.dist);
}
}

interface WardsLike {
function wards(address who) external view returns (uint256);
}

interface DssVestWithGemLike {
function gem() external view returns (address);
}

interface StakingRewardsLike {
function owner() external view returns (address);

function rewardRate() external view returns (uint256);

function rewardsDistribution() external view returns (address);

function rewardsToken() external view returns (address);

function stakingToken() external view returns (address);
}

interface VestedRewardsDistributionLike {
function dssVest() external view returns (address);

function gem() external view returns (address);

function stakingRewards() external view returns (address);
}

interface ChainlogLike {
function getAddress(bytes32 key) external view returns (address);

function setAddress(bytes32 key, address addr) external;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"lsmkr": "address: the address of LSMKR",
"spk": "address: the address of SPK",
"vest": "address: the address of a DssVestMintable contract for SPK",
"rewards": "[OPTIONAL] address: the address of the StakingRewards contract",
"dist": "[OPTIONAL] address: the address of the VestedRewardsDistrubution contract"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"lsmkr": "address: the address of LSMKR",
"spk": "address: the address of SPK",
"vest": "address: the address of a DssVestMintable contract for SPK",
"rewards": "[OPTIONAL] address: the address of the StakingRewards contract",
"dist": "[OPTIONAL] address: the address of the VestedRewardsDistrubution contract"
}
76 changes: 76 additions & 0 deletions script/phase-1d/31-LsmkrSpkFarmingDeploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-FileCopyrightText: © 2023 Dai Foundation <www.daifoundation.org>
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
pragma solidity ^0.8.16;

import {Script} from "forge-std/Script.sol";
import {ScriptTools} from "dss-test/ScriptTools.sol";

import {Reader} from "../helpers/Reader.sol";
import {StakingRewardsDeploy, StakingRewardsDeployParams} from "../dependencies/StakingRewardsDeploy.sol";
import {
VestedRewardsDistributionDeploy,
VestedRewardsDistributionDeployParams
} from "../dependencies/VestedRewardsDistributionDeploy.sol";

contract Phase1d_LsmkrSpkFarmingDeployScript is Script {
ChainlogLike internal constant chainlog = ChainlogLike(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F);

string internal constant NAME = "phase-1d/lsmkr-spk-farming-deploy";

function run() external {
Reader reader = new Reader(ScriptTools.loadConfig());

address admin = chainlog.getAddress("MCD_PAUSE_PROXY");

address lsmkr = reader.envOrReadAddress("FOUNDRY_LSMKR", ".lsmkr");
address spk = reader.envOrReadAddress("FOUNDRY_SPK", ".spk");
address vest = reader.envOrReadAddress("FOUNDRY_VEST", ".vest");
address dist = reader.readAddressOptional(".dist");
address rewards = reader.readAddressOptional(".rewards");

vm.startBroadcast();

if (rewards == address(0)) {
rewards = StakingRewardsDeploy.deploy(
StakingRewardsDeployParams({owner: admin, stakingToken: lsmkr, rewardsToken: spk})
);
}

if (dist == address(0)) {
dist = VestedRewardsDistributionDeploy.deploy(
VestedRewardsDistributionDeployParams({
deployer: msg.sender,
owner: admin,
vest: vest,
rewards: rewards
})
);
}

vm.stopBroadcast();

ScriptTools.exportContract(NAME, "admin", admin);
ScriptTools.exportContract(NAME, "spk", spk);
ScriptTools.exportContract(NAME, "lsmkr", lsmkr);
ScriptTools.exportContract(NAME, "dist", dist);
ScriptTools.exportContract(NAME, "rewards", rewards);
ScriptTools.exportContract(NAME, "vest", vest);
}
}

interface ChainlogLike {
function getAddress(bytes32 _key) external view returns (address addr);
}
100 changes: 100 additions & 0 deletions script/phase-1d/32-LsmkrSpkFarmingInit.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// SPDX-FileCopyrightText: © 2023 Dai Foundation <www.daifoundation.org>
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
pragma solidity ^0.8.16;

import {Script} from "forge-std/Script.sol";
import {ScriptTools} from "dss-test/ScriptTools.sol";

import {Reader} from "../helpers/Reader.sol";
import {
LsmkrSpkFarmingInit,
LsmkrSpkFarmingInitParams,
LsmkrSpkFarmingInitResult
} from "../dependencies/phase-1d/LsmkrSpkFarmingInit.sol";

contract Phase1d_LsmkrSpkFarmingInitScript is Script {
using ScriptTools for string;

ChainlogLike internal constant chainlog = ChainlogLike(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F);

string internal constant NAME = "phase-1d/lsmkr-spk-farming-init";

function run() external {
Reader config = new Reader(ScriptTools.loadConfig());
Reader deps = new Reader(ScriptTools.loadDependencies());

uint256 vestTot = config.envOrReadUint("FOUNDRY_VEST_TOT", ".vestTot");
uint256 vestBgn = config.envOrReadUint("FOUNDRY_VEST_BGN", ".vestBgn");
uint256 vestTau = config.envOrReadUint("FOUNDRY_VEST_TAU", ".vestTau");

address lsmkr = deps.envOrReadAddress("FOUNDRY_LSMKR", ".lsmkr");
address spk = deps.envOrReadAddress("FOUNDRY_SPK", ".spk");
address dist = deps.envOrReadAddress("FOUNDRY_DIST", ".dist");
address rewards = deps.envOrReadAddress("FOUNDRY_FARM", ".rewards");
address vest = deps.envOrReadAddress("FOUNDRY_VEST", ".vest");

LsmkrSpkFarmingInitParams memory farmingCfg = LsmkrSpkFarmingInitParams({
spk: spk,
lsmkr: lsmkr,
dist: dist,
distKey: "REWARDS_DISTRIBUTION_LSMKR_SPK",
rewards: rewards,
rewardsKey: "FARM_LSMKR_SPK",
vest: vest,
vestTot: vestTot,
vestBgn: vestBgn,
vestTau: vestTau
});

address pauseProxy = chainlog.getAddress("MCD_PAUSE_PROXY");

vm.startBroadcast();

LsmkrSpkFarmingInitSpell spell = new LsmkrSpkFarmingInitSpell();
bytes memory out = ProxyLike(pauseProxy).exec(address(spell), abi.encodeCall(spell.cast, (farmingCfg)));

vm.stopBroadcast();

LsmkrSpkFarmingInitResult memory res = abi.decode(out, (LsmkrSpkFarmingInitResult));

ScriptTools.exportContract(NAME, "spk", spk);
ScriptTools.exportContract(NAME, "dist", dist);
ScriptTools.exportContract(NAME, "rewards", rewards);
ScriptTools.exportContract(NAME, "vest", vest);
ScriptTools.exportValue(NAME, "vestId", res.vestId);
}
}

contract LsmkrSpkFarmingInitSpell {
uint256 internal constant CAP = type(uint256).max;

function cast(LsmkrSpkFarmingInitParams memory farmingCfg) public returns (LsmkrSpkFarmingInitResult memory) {
DssVestLike(farmingCfg.vest).file("cap", CAP);
return LsmkrSpkFarmingInit.init(farmingCfg);
}
}

interface ProxyLike {
function exec(address usr, bytes memory fax) external returns (bytes memory out);
}

interface ChainlogLike {
function getAddress(bytes32 _key) external view returns (address addr);
}

interface DssVestLike {
function file(bytes32 _what, uint256 _data) external;
}
Loading

0 comments on commit d785557

Please sign in to comment.