Skip to content

Commit

Permalink
Chore: update code and reports after audits (#26)
Browse files Browse the repository at this point in the history
* chore: update with the latest audit reports

* fix: bad audit file name

* refactor: remove `VestInit.init`

The ownership of `DssVest` no longer lies with this module, instead it assumes that DssVest is already properly initialized and can be used to create vesting streams.

* fix: enable optimizations for `DssVest`

* refactor: make changes suggested by Spearbit audit

* refactor(UsdsSkyFarmingInit): add missing check for `owner`

* refactor(UsdsSkyFarmingInit): reorganize sanity checks
  • Loading branch information
amusingaxl authored Sep 6, 2024
1 parent 1ecc6d6 commit 1426851
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 41 deletions.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ script = 'script'
libs = ['lib']
solc_version = '0.8.16'
optimizer = true
optimizer_runs = 200
unchecked_cheatcode_artifacts = true
fs_permissions = [
{ access = "read", path = "./out/" },
Expand All @@ -28,7 +29,8 @@ script = 'script-0_6_x'
# you can install it with the default profile.
libs = ['lib-0_6_x', 'lib']
solc_version = '0.6.12'
optimizer = false
optimizer = true
optimizer_runs = 200
unchecked_cheatcode_artifacts = true
fs_permissions = [
{ access = "read", path = "./out/" },
Expand Down
11 changes: 1 addition & 10 deletions script/dependencies/VestInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@

pragma solidity ^0.8.16;

struct VestInitParams {
uint256 cap;
}

struct VestCreateParams {
address usr;
uint256 tot;
Expand All @@ -27,11 +23,8 @@ struct VestCreateParams {
uint256 eta;
}

/// @dev Handles vesting stream creation. Assumes `DssVest` parameters are initialized somewhere else.
library VestInit {
function init(address vest, VestInitParams memory p) internal {
DssVestLike(vest).file("cap", p.cap);
}

function create(address vest, VestCreateParams memory p) internal returns (uint256 vestId) {
vestId = DssVestLike(vest).create(
p.usr,
Expand All @@ -47,8 +40,6 @@ library VestInit {
}

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

function create(
address _usr,
uint256 _tot,
Expand Down
11 changes: 7 additions & 4 deletions script/dependencies/phase-1b/Usds01PreFarmingInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ library Usds01PreFarmingInit {
StakingRewardsLike(p.rewards).rewardsToken() == address(0),
"Usds01PreFarmingInit/invalid-rewards-token"
);
require(StakingRewardsLike(p.rewards).rewardRate() == 0, "Usds01PreFarmingInit/reward-rate-not-zero");
require(
StakingRewardsLike(p.rewards).lastUpdateTime() == 0,
"Usds01PreFarmingInit/rewards-last-update-time-invalid"
StakingRewardsLike(p.rewards).rewardsDistribution() == address(0),
"Usds01PreFarmingInit/rewards-distribution-already-set"
);
require(
StakingRewardsLike(p.rewards).owner() == chainlog.getAddress("MCD_PAUSE_PROXY"),
Expand All @@ -47,10 +48,12 @@ library Usds01PreFarmingInit {
}

interface StakingRewardsLike {
function lastUpdateTime() external view returns (uint256);

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);
Expand Down
33 changes: 22 additions & 11 deletions script/dependencies/phase-1b/UsdsSkyFarmingInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,24 @@ library UsdsSkyFarmingInit {
ChainlogLike internal constant chainlog = ChainlogLike(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F);

function init(UsdsSkyFarmingInitParams memory p) internal returns (UsdsSkyFarmingInitResult memory r) {
address stakingToken = StakingRewardsLike(p.rewards).stakingToken();
address rewardsToken = StakingRewardsLike(p.rewards).rewardsToken();

require(stakingToken != rewardsToken, "UsdsSkyFarmingInit/rewards-token-same-as-staking-token");

require(DssVestWithGemLike(p.vest).gem() == p.sky, "UsdsSkyFarmingInit/vest-gem-mismatch");

require(stakingToken == p.usds, "UsdsSkyFarmingInit/rewards-staking-token-mismatch");
require(rewardsToken == p.sky, "UsdsSkyFarmingInit/rewards-rewards-token-mismatch");
require(
StakingRewardsLike(p.rewards).lastUpdateTime() == 0,
"UsdsSkyFarmingInit/rewards-last-update-time-invalid"
StakingRewardsLike(p.rewards).stakingToken() == p.usds,
"UsdsSkyFarmingInit/rewards-staking-token-mismatch"
);
require(
StakingRewardsLike(p.rewards).rewardsToken() == p.sky,
"UsdsSkyFarmingInit/rewards-rewards-token-mismatch"
);
require(StakingRewardsLike(p.rewards).rewardRate() == 0, "UsdsSkyFarmingInit/reward-rate-not-zero");
require(
StakingRewardsLike(p.rewards).rewardsDistribution() == address(0),
"UsdsSkyFarmingInit/rewards-distribution-already-set"
);
require(
StakingRewardsLike(p.rewards).owner() == chainlog.getAddress("MCD_PAUSE_PROXY"),
"UsdsSkyFarmingInit/invalid-owner"
);

require(VestedRewardsDistributionLike(p.dist).gem() == p.sky, "UsdsSkyFarmingInit/dist-gem-mismatch");
Expand All @@ -64,7 +70,6 @@ library UsdsSkyFarmingInit {
// `vest` is expected to be an instance of `DssVestMintable`.
// Check if minting rights on `sky` were granted to `vest`.
require(WardsLike(p.sky).wards(p.vest) == 1, "UsdsSkyFarmingInit/missing-sky-rely-vest");

// Set `dist` with `rewardsDistribution` role in `rewards`.
StakingRewardsInit.init(p.rewards, StakingRewardsInitParams({dist: p.dist}));

Expand Down Expand Up @@ -93,7 +98,11 @@ interface DssVestWithGemLike {
}

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

function rewardRate() external view returns (uint256);

function rewardsDistribution() external view returns (address);

function rewardsToken() external view returns (address);

Expand All @@ -109,5 +118,7 @@ interface VestedRewardsDistributionLike {
}

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

function setAddress(bytes32 key, address addr) external;
}
21 changes: 9 additions & 12 deletions script/phase-1b/02-UsdsSkyFarmingInit.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {Script} from "forge-std/Script.sol";
import {ScriptTools} from "dss-test/ScriptTools.sol";

import {Reader} from "../helpers/Reader.sol";
import {VestInit, VestInitParams} from "../dependencies/VestInit.sol";
import {
UsdsSkyFarmingInit,
UsdsSkyFarmingInitParams,
Expand Down Expand Up @@ -60,17 +59,12 @@ contract Phase1b_UsdsSkyFarmingInitScript is Script {
vestTau: vestTau
});

VestInitParams memory vestInitCfg = VestInitParams({cap: type(uint256).max});

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

vm.startBroadcast();

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

vm.stopBroadcast();

Expand All @@ -85,11 +79,10 @@ contract Phase1b_UsdsSkyFarmingInitScript is Script {
}

contract UsdsSkyFarmingInitSpell {
function cast(
UsdsSkyFarmingInitParams memory farmingCfg,
VestInitParams calldata vestInitCfg
) public returns (UsdsSkyFarmingInitResult memory) {
VestInit.init(farmingCfg.vest, vestInitCfg);
uint256 internal constant CAP = type(uint256).max;

function cast(UsdsSkyFarmingInitParams memory farmingCfg) public returns (UsdsSkyFarmingInitResult memory) {
DssVestLike(farmingCfg.vest).file("cap", CAP);
return UsdsSkyFarmingInit.init(farmingCfg);
}
}
Expand All @@ -101,3 +94,7 @@ interface ProxyLike {
interface ChainlogLike {
function getAddress(bytes32 _key) external view returns (address addr);
}

interface DssVestLike {
function file(bytes32 _what, uint256 _data) external;
}
19 changes: 16 additions & 3 deletions script/phase-1b/03-UsdsSkyFarmingCheck.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
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";

contract Phase1b_UsdsSkyFarmingCheckScript is Script {
function run() external returns (bool) {
Reader deps = new Reader("");
deps.loadDependenciesOrConfig();
Reader config = new Reader(ScriptTools.loadConfig());
Reader deps = new Reader(ScriptTools.loadDependencies());

address admin = deps.envOrReadAddress("FOUNDRY_ADMIN", ".admin");
address sky = deps.envOrReadAddress("FOUNDRY_SKY", ".sky");
Expand All @@ -30,6 +31,9 @@ contract Phase1b_UsdsSkyFarmingCheckScript is Script {
address rewards = deps.readAddress(".rewards");
address vest = deps.readAddress(".vest");
uint256 vestId = deps.readUint(".vestId");
uint256 vestBgn = config.readUint(".vestBgn");
uint256 vestTau = config.readUint(".vestTau");
uint256 vestTot = config.readUint(".vestTot");

require(VestedRewardsDistributionLike(dist).dssVest() == vest, "VestedRewardsDistribution/invalid-vest");
require(VestedRewardsDistributionLike(dist).vestId() == vestId, "VestedRewardsDistribution/invalid-vest-id");
Expand All @@ -41,7 +45,7 @@ contract Phase1b_UsdsSkyFarmingCheckScript is Script {

require(StakingRewardsLike(rewards).owner() == admin, "StakingRewards/admin-not-owner");
require(StakingRewardsLike(rewards).rewardsToken() == sky, "StakingRewards/invalid-rewards-token");
require(StakingRewardsLike(rewards).stakingToken() == usds, "StakingRewards/invalid-rewards-token");
require(StakingRewardsLike(rewards).stakingToken() == usds, "StakingRewards/invalid-staking-token");
require(
StakingRewardsLike(rewards).rewardsDistribution() == dist,
"StakingRewards/invalid-rewards-distribution"
Expand All @@ -54,6 +58,9 @@ contract Phase1b_UsdsSkyFarmingCheckScript is Script {
require(DssVestWithGemLike(vest).res(vestId) == 1, "DssVest/invalid-vest-res");
require(DssVestWithGemLike(vest).usr(vestId) == dist, "DssVest/wrong-dist");
require(DssVestWithGemLike(vest).mgr(vestId) == address(0), "DssVest/mgr-should-not-be-set");
require(DssVestWithGemLike(vest).bgn(vestId) == vestBgn, "DssVest/invalid-bgn");
require(DssVestWithGemLike(vest).fin(vestId) == vestBgn + vestTau, "DssVest/invalid-tau");
require(DssVestWithGemLike(vest).tot(vestId) == vestTot, "DssVest/invalid-tot");

return true;
}
Expand Down Expand Up @@ -84,12 +91,18 @@ interface StakingRewardsLike {
}

interface DssVestWithGemLike {
function bgn(uint256 _id) external view returns (uint256);

function fin(uint256 _id) external view returns (uint256);

function gem() external view returns (address);

function mgr(uint256 _id) external view returns (address);

function res(uint256 _id) external view returns (uint256);

function tot(uint256 _id) external view returns (uint256);

function usr(uint256 _id) external view returns (address);

function valid(uint256 _id) external view returns (bool);
Expand Down

0 comments on commit 1426851

Please sign in to comment.