diff --git a/README.md b/README.md index 02781be..78426fb 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ A technical description of the components of the LockStake Engine (LSE). The LockstakeEngine is the main contract in the set of contracts that implement and support the LSE. On a high level, it supports locking MKR in the contract, and using it to: * Vote through a delegate contract. -* Farm NST or SDAO tokens. -* Borrow NST through a vault. +* Farm USDS or SDAO tokens. +* Borrow USDS through a vault. When withdrawing back the MKR the user has to pay an exit fee. -There is also support for locking and freeing NGT instead of MKR. +There is also support for locking and freeing SKY instead of MKR. **System Attributes:** @@ -20,7 +20,7 @@ There is also support for locking and freeing NGT instead of MKR. * MKR cannot be moved outside of an `urn` or between `urn`s without paying the exit fee. * At any time the `urn`'s entire locked MKR amount is either staked or not, and is either delegated or not. * Staking rewards are not part of the collateral, and are still claimable after freeing from the engine, changing a farm or being liquidated. -* The entire locked MKR amount is also credited as collateral for the user. However, the user itself decides if and how much NST to borrow, and should be aware of liquidation risk. +* The entire locked MKR amount is also credited as collateral for the user. However, the user itself decides if and how much USDS to borrow, and should be aware of liquidation risk. * A user can delegate control of an `urn` that it controls to another EOA/contract. This is helpful for supporting manager-type contracts that can be built on top of the engine. * Once a vault goes into liquidation, its MKR is undelegated and unstaked. It and can only be re-delegated or re-staked once there are no more auctions for it. @@ -30,15 +30,15 @@ There is also support for locking and freeing NGT instead of MKR. * `hope(address owner, uint256 index, address usr)` - Allow `usr` to also manage the `owner-index` `urn`. * `nope(address owner, uint256 index, address usr)` - Disallow `usr` from managing the `owner-index` `urn`. * `lock(address owner, uint256 index, uint256 wad, uint16 ref)` - Deposit `wad` amount of MKR into the `owner-index` `urn`. This also delegates the MKR to the chosen delegate (if such exists) and stakes it to the chosen farm (if such exists) using the `ref` code. -* `lockNgt(address owner, uint256 index, uint256 ngtWad, uint16 ref)` - Deposit `ngtWad` amount of NGT. The NGT is first converted to MKR, which then gets deposited into the `owner-index` `urn`. This also delegates the MKR to the chosen delegate (if such exists) and stakes it to the chosen farm (if such exists) using the `ref` code. +* `lockSky(address owner, uint256 index, uint256 skyWad, uint16 ref)` - Deposit `skyWad` amount of SKY. The SKY is first converted to MKR, which then gets deposited into the `owner-index` `urn`. This also delegates the MKR to the chosen delegate (if such exists) and stakes it to the chosen farm (if such exists) using the `ref` code. * `free(address owner, uint256 index, address to, uint256 wad)` - Withdraw `wad` amount of MKR from the `owner-index` `urn` to the `to` address (which will receive it minus the exit fee). This will undelegate the requested amount of MKR (if a delegate was chosen) and unstake it (if a farm was chosen). It will require the user to pay down debt beforehand if needed. -* `freeNgt(address owner, uint256 index, address to, uint256 ngtWad)` - Withdraw `ngtWad - ngtWad % mkrNgtRate` amount of NGT to the `to` address. In practice, a proportional amount of MKR is first freed from the `owner-index` `urn` (minus the exit fee), then gets converted to NGT and sent out. This will undelegate the MKR (if a delegate was chosen) and unstake it (if a farm was chosen). It will require the user to pay down debt beforehand if needed. Note that freeing NGT is possible even if the position was previously entered via regular locking (using MKR), and vice-vera. +* `freeSky(address owner, uint256 index, address to, uint256 skyWad)` - Withdraw `skyWad - skyWad % mkrSkyRate` amount of SKY to the `to` address. In practice, a proportional amount of MKR is first freed from the `owner-index` `urn` (minus the exit fee), then gets converted to SKY and sent out. This will undelegate the MKR (if a delegate was chosen) and unstake it (if a farm was chosen). It will require the user to pay down debt beforehand if needed. Note that freeing SKY is possible even if the position was previously entered via regular locking (using MKR), and vice-vera. * `freeNoFee(address owner, uint256 index, address to, uint256 wad)` - Withdraw `wad` amount of MKR from the `owner-index` `urn` to the `to` address without paying any fee. This will undelegate the requested amount of MKR (if a delegate was chosen) and unstake it (if a farm was chosen). It will require the user to pay down debt beforehand if needed. This function can only be called by an address which was both authorized on the contract by governance and for which the urn owner has called `hope`. It is useful for implementing a migration contract that will move the funds to another engine contract (if ever needed). * `selectVoteDelegate(address owner, uint256 index, address voteDelegate)` - Choose which delegate contract to delegate the `owner-index` `urn`'s entire MKR amount to. In case it is `address(0)` the MKR will stay (or become) undelegated. * `selectFarm(address owner, uint256 index, address farm, uint16 ref)` - Select which farm (from the whitelisted ones) to stake the `owner-index` `urn`'s MKR to (along with the `ref` code). In case it is `address(0)` the MKR will stay (or become) unstaked. -* `draw(address owner, uint256 index, address to, uint256 wad)` - Generate `wad` amount of NST using the `owner-index` `urn`’s MKR as collateral and send it to the `to` address. -* `wipe(address owner, uint256 index, uint256 wad)` - Repay `wad` amount of NST backed by the `owner-index` `urn`’s MKR. -* `wipeAll(address owner, uint256 index)` - Repay the amount of NST that is needed to wipe the `owner-index` `urn`’s entire debt. +* `draw(address owner, uint256 index, address to, uint256 wad)` - Generate `wad` amount of USDS using the `owner-index` `urn`’s MKR as collateral and send it to the `to` address. +* `wipe(address owner, uint256 index, uint256 wad)` - Repay `wad` amount of USDS backed by the `owner-index` `urn`’s MKR. +* `wipeAll(address owner, uint256 index)` - Repay the amount of USDS that is needed to wipe the `owner-index` `urn`’s entire debt. * `getReward(address owner, uint256 index, address farm, address to)` - Claim the reward generated from a farm on behalf of the `owner-index` `urn` and send it to the specified `to` address. * `multicall(bytes[] calldata data)` - Batch multiple methods in a single call to the contract. @@ -188,11 +188,11 @@ In general participating in MKR liquidations should be pretty straightforward us Current Makerdao ecosystem keepers expect receiving collateral in the form of `vat.gem` (usually to a keeper arbitrage callee contract), which they then need to `exit` to ERC20 from. However the LSE liquidation mechanism sends the MKR directly in the form of ERC20, which requires a slight change in the keepers mode of operation. For example, keepers using the Maker supplied [exchange-callee for Uniswap V2](https://github.com/makerdao/exchange-callees/blob/3b080ecd4169fe09a59be51e2f85ddcea3242461/src/UniswapV2Callee.sol#L109) would need to use a version that gets the `gem` instead of the `gemJoin` and does not call `gemJoin.exit`. -Additionaly, the callee might need to convert the MKR to NGT, in case it interacts with the NST/NGT Uniswap pool. +Additionaly, the callee might need to convert the MKR to SKY, in case it interacts with the USDS/SKY Uniswap pool. ## 5. Splitter -The Splitter contract is in charge of distributing the Surplus Buffer funds on each `vow.flap` to the Smart Burn Engine (SBE) and the LSE's NST farm. The total amount sent each time is `vow.bump`. +The Splitter contract is in charge of distributing the Surplus Buffer funds on each `vow.flap` to the Smart Burn Engine (SBE) and the LSE's USDS farm. The total amount sent each time is `vow.bump`. To accomplish this, it exposes a `kick` operation to be triggered periodically. Its logic withdraws DAI from the `vow` and splits it in two parts. The first part (`burn`) is sent to the underlying `flapper` contract to be processed by the SBE. The second part (`WAD - burn`) is distributed as reward to a `farm` contract. Note that `burn == 1 WAD` indicates funneling 100% of the DAI to the SBE without sending any rewards to the farm. @@ -207,7 +207,7 @@ The Splitter implements rate-limiting using a `hop` parameter. ## 6. StakingRewards -The LSE uses a Maker modified [version](https://github.com/makerdao/endgame-toolkit/blob/master/README.md#stakingrewards) of the Synthetix Staking Reward as the farm for distributing NST to stakers. +The LSE uses a Maker modified [version](https://github.com/makerdao/endgame-toolkit/blob/master/README.md#stakingrewards) of the Synthetix Staking Reward as the farm for distributing USDS to stakers. For compatibility with the SBE, the assumption is that the duration of each farming distribution (`farm.rewardsDuration`) is similar to the flapper's cooldown period (`flap.hop`). This in practice divides the overall farming reward distribution to a set of smaller non overlapping distributions. It also allows for periods where there is no distribution at all. @@ -218,8 +218,8 @@ The StakingRewards contract `setRewardsDuration` function was modified to enable * `rewardsDuration` - The amount of seconds each distribution should take. ## General Notes -* In many of the modules, such as the splitter and the flappers, NST can replace DAI. This will usually require a deployment of the contract with NstJoin as a replacement of the DaiJoin address. +* In many of the modules, such as the splitter and the flappers, USDS can replace DAI. This will usually require a deployment of the contract with UsdsJoin as a replacement of the DaiJoin address. * The LSE assumes that the ESM threshold is set large enough prior to its deployment, so Emergency Shutdown can never be called. * Freeing very small amounts could bypass the exit fees (due to the rounding down) but since the LSE is meant to only be deployed on Ethereum, this is assumed to not be economically viable. * As opposed to other collateral types, if a user notices an upcoming governance action that can hurt their position (or that they just don't like), they can not exit their position without losing the exit fee. -* It is assumed that MKR to/from NGT conversions are not blocked. +* It is assumed that MKR to/from SKY conversions are not blocked. diff --git a/deploy/LockstakeDeploy.sol b/deploy/LockstakeDeploy.sol index bf97dd8..fde6baa 100644 --- a/deploy/LockstakeDeploy.sol +++ b/deploy/LockstakeDeploy.sol @@ -30,15 +30,15 @@ library LockstakeDeploy { address deployer, address owner, address voteDelegateFactory, - address nstJoin, + address usdsJoin, bytes32 ilk, - address mkrNgt, + address mkrSky, bytes4 calcSig ) internal returns (LockstakeInstance memory lockstakeInstance) { DssInstance memory dss = MCD.loadFromChainlog(0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F); lockstakeInstance.lsmkr = address(new LockstakeMkr()); - lockstakeInstance.engine = address(new LockstakeEngine(voteDelegateFactory, nstJoin, ilk, mkrNgt, lockstakeInstance.lsmkr)); + lockstakeInstance.engine = address(new LockstakeEngine(voteDelegateFactory, usdsJoin, ilk, mkrSky, lockstakeInstance.lsmkr)); lockstakeInstance.clipper = address(new LockstakeClipper(address(dss.vat), address(dss.spotter), address(dss.dog), lockstakeInstance.engine)); (bool ok, bytes memory returnV) = dss.chainlog.getAddress("CALC_FAB").call(abi.encodeWithSelector(calcSig, owner)); require(ok); diff --git a/deploy/LockstakeInit.sol b/deploy/LockstakeInit.sol index e0740e2..57809d2 100644 --- a/deploy/LockstakeInit.sol +++ b/deploy/LockstakeInit.sol @@ -26,14 +26,14 @@ interface LockstakeMkrLike { interface LockstakeEngineLike { function voteDelegateFactory() external view returns (address); function vat() external view returns (address); - function nstJoin() external view returns (address); - function nst() external view returns (address); + function usdsJoin() external view returns (address); + function usds() external view returns (address); function ilk() external view returns (bytes32); function mkr() external view returns (address); function lsmkr() external view returns (address); function fee() external view returns (uint256); - function mkrNgt() external view returns (address); - function ngt() external view returns (address); + function mkrSky() external view returns (address); + function sky() external view returns (address); function rely(address) external; function file(bytes32, address) external; function file(bytes32, uint256) external; @@ -98,11 +98,11 @@ interface IlkRegistryLike { struct LockstakeConfig { bytes32 ilk; address voteDelegateFactory; - address nstJoin; - address nst; + address usdsJoin; + address usds; address mkr; - address mkrNgt; - address ngt; + address mkrSky; + address sky; address[] farms; uint256 fee; uint256 maxLine; @@ -146,13 +146,13 @@ library LockstakeInit { // Sanity checks require(engine.voteDelegateFactory() == cfg.voteDelegateFactory, "Engine voteDelegateFactory mismatch"); require(engine.vat() == address(dss.vat), "Engine vat mismatch"); - require(engine.nstJoin() == cfg.nstJoin, "Engine nstJoin mismatch"); - require(engine.nst() == cfg.nst, "Engine nst mismatch"); + require(engine.usdsJoin() == cfg.usdsJoin, "Engine usdsJoin mismatch"); + require(engine.usds() == cfg.usds, "Engine usds mismatch"); require(engine.ilk() == cfg.ilk, "Engine ilk mismatch"); require(engine.mkr() == cfg.mkr, "Engine mkr mismatch"); require(engine.lsmkr() == lockstakeInstance.lsmkr, "Engine lsmkr mismatch"); - require(engine.mkrNgt() == cfg.mkrNgt, "Engine mkrNgt mismatch"); - require(engine.ngt() == cfg.ngt, "Engine ngt mismatch"); + require(engine.mkrSky() == cfg.mkrSky, "Engine mkrSky mismatch"); + require(engine.sky() == cfg.sky, "Engine sky mismatch"); require(clipper.ilk() == cfg.ilk, "Clipper ilk mismatch"); require(clipper.vat() == address(dss.vat), "Clipper vat mismatch"); require(clipper.engine() == address(engine), "Clipper engine mismatch"); diff --git a/src/LockstakeEngine.sol b/src/LockstakeEngine.sol index f5054cc..e4e019b 100644 --- a/src/LockstakeEngine.sol +++ b/src/LockstakeEngine.sol @@ -37,9 +37,9 @@ interface VatLike { function grab(bytes32, address, address, address, int256, int256) external; } -interface NstJoinLike { +interface UsdsJoinLike { function vat() external view returns (VatLike); - function nst() external view returns (GemLike); + function usds() external view returns (GemLike); function join(address, uint256) external; function exit(address, uint256) external; } @@ -56,12 +56,12 @@ interface JugLike { function drip(bytes32) external returns (uint256); } -interface MkrNgtLike { +interface MkrSkyLike { function rate() external view returns (uint256); function mkr() external view returns (GemLike); - function ngt() external view returns (GemLike); - function ngtToMkr(address, uint256) external; - function mkrToNgt(address, uint256) external; + function sky() external view returns (GemLike); + function skyToMkr(address, uint256) external; + function mkrToSky(address, uint256) external; } contract LockstakeEngine is Multicall { @@ -90,14 +90,14 @@ contract LockstakeEngine is Multicall { VoteDelegateFactoryLike immutable public voteDelegateFactory; VatLike immutable public vat; - NstJoinLike immutable public nstJoin; - GemLike immutable public nst; + UsdsJoinLike immutable public usdsJoin; + GemLike immutable public usds; bytes32 immutable public ilk; GemLike immutable public mkr; GemLike immutable public lsmkr; - MkrNgtLike immutable public mkrNgt; - GemLike immutable public ngt; - uint256 immutable public mkrNgtRate; + MkrSkyLike immutable public mkrSky; + GemLike immutable public sky; + uint256 immutable public mkrSkyRate; address immutable public urnImplementation; // --- events --- @@ -114,9 +114,9 @@ contract LockstakeEngine is Multicall { event SelectVoteDelegate(address indexed owner, uint256 indexed index, address indexed voteDelegate); event SelectFarm(address indexed owner, uint256 indexed index, address indexed farm, uint16 ref); event Lock(address indexed owner, uint256 indexed index, uint256 wad, uint16 ref); - event LockNgt(address indexed owner, uint256 indexed index, uint256 ngtWad, uint16 ref); + event LockSky(address indexed owner, uint256 indexed index, uint256 skyWad, uint16 ref); event Free(address indexed owner, uint256 indexed index, address to, uint256 wad, uint256 freed); - event FreeNgt(address indexed owner, uint256 indexed index, address to, uint256 ngtWad, uint256 ngtFreed); + event FreeSky(address indexed owner, uint256 indexed index, address to, uint256 skyWad, uint256 skyFreed); event FreeNoFee(address indexed owner, uint256 indexed index, address to, uint256 wad); event Draw(address indexed owner, uint256 indexed index, address to, uint256 wad); event Wipe(address indexed owner, uint256 indexed index, uint256 wad); @@ -134,22 +134,22 @@ contract LockstakeEngine is Multicall { // --- constructor --- - constructor(address voteDelegateFactory_, address nstJoin_, bytes32 ilk_, address mkrNgt_, address lsmkr_) { + constructor(address voteDelegateFactory_, address usdsJoin_, bytes32 ilk_, address mkrSky_, address lsmkr_) { voteDelegateFactory = VoteDelegateFactoryLike(voteDelegateFactory_); - nstJoin = NstJoinLike(nstJoin_); - vat = nstJoin.vat(); - nst = nstJoin.nst(); + usdsJoin = UsdsJoinLike(usdsJoin_); + vat = usdsJoin.vat(); + usds = usdsJoin.usds(); ilk = ilk_; - mkrNgt = MkrNgtLike(mkrNgt_); - mkr = mkrNgt.mkr(); - ngt = mkrNgt.ngt(); - mkrNgtRate = mkrNgt.rate(); + mkrSky = MkrSkyLike(mkrSky_); + mkr = mkrSky.mkr(); + sky = mkrSky.sky(); + mkrSkyRate = mkrSky.rate(); lsmkr = GemLike(lsmkr_); urnImplementation = address(new LockstakeUrn(address(vat), lsmkr_)); - vat.hope(nstJoin_); - nst.approve(nstJoin_, type(uint256).max); - ngt.approve(address(mkrNgt), type(uint256).max); - mkr.approve(address(mkrNgt), type(uint256).max); + vat.hope(usdsJoin_); + usds.approve(usdsJoin_, type(uint256).max); + sky.approve(address(mkrSky), type(uint256).max); + mkr.approve(address(mkrSky), type(uint256).max); wards[msg.sender] = 1; emit Rely(msg.sender); @@ -320,12 +320,12 @@ contract LockstakeEngine is Multicall { emit Lock(owner, index, wad, ref); } - function lockNgt(address owner, uint256 index, uint256 ngtWad, uint16 ref) external { + function lockSky(address owner, uint256 index, uint256 skyWad, uint16 ref) external { address urn = _getUrn(owner, index); - ngt.transferFrom(msg.sender, address(this), ngtWad); - mkrNgt.ngtToMkr(address(this), ngtWad); - _lock(urn, ngtWad / mkrNgtRate, ref); - emit LockNgt(owner, index, ngtWad, ref); + sky.transferFrom(msg.sender, address(this), skyWad); + mkrSky.skyToMkr(address(this), skyWad); + _lock(urn, skyWad / mkrSkyRate, ref); + emit LockSky(owner, index, skyWad, ref); } function _lock(address urn, uint256 wad, uint16 ref) internal { @@ -352,13 +352,13 @@ contract LockstakeEngine is Multicall { emit Free(owner, index, to, wad, freed); } - function freeNgt(address owner, uint256 index, address to, uint256 ngtWad) external returns (uint256 ngtFreed) { + function freeSky(address owner, uint256 index, address to, uint256 skyWad) external returns (uint256 skyFreed) { address urn = _getAuthedUrn(owner, index); - uint256 wad = ngtWad / mkrNgtRate; + uint256 wad = skyWad / mkrSkyRate; uint256 freed = _free(urn, wad, fee); - ngtFreed = freed * mkrNgtRate; - mkrNgt.mkrToNgt(to, freed); - emit FreeNgt(owner, index, to, ngtWad, ngtFreed); + skyFreed = freed * mkrSkyRate; + mkrSky.mkrToSky(to, freed); + emit FreeSky(owner, index, to, skyWad, skyFreed); } function freeNoFee(address owner, uint256 index, address to, uint256 wad) external auth { @@ -396,14 +396,14 @@ contract LockstakeEngine is Multicall { uint256 dart = _divup(wad * RAY, rate); require(dart <= uint256(type(int256).max), "LockstakeEngine/overflow"); vat.frob(ilk, urn, address(0), address(this), 0, int256(dart)); - nstJoin.exit(to, wad); + usdsJoin.exit(to, wad); emit Draw(owner, index, to, wad); } function wipe(address owner, uint256 index, uint256 wad) external { address urn = _getUrn(owner, index); - nst.transferFrom(msg.sender, address(this), wad); - nstJoin.join(address(this), wad); + usds.transferFrom(msg.sender, address(this), wad); + usdsJoin.join(address(this), wad); (, uint256 rate,,,) = vat.ilks(ilk); uint256 dart = wad * RAY / rate; require(dart <= uint256(type(int256).max), "LockstakeEngine/overflow"); @@ -417,8 +417,8 @@ contract LockstakeEngine is Multicall { require(art <= uint256(type(int256).max), "LockstakeEngine/overflow"); (, uint256 rate,,,) = vat.ilks(ilk); wad = _divup(art * rate, RAY); - nst.transferFrom(msg.sender, address(this), wad); - nstJoin.join(address(this), wad); + usds.transferFrom(msg.sender, address(this), wad); + usdsJoin.join(address(this), wad); vat.frob(ilk, urn, address(0), address(this), 0, -int256(art)); emit Wipe(owner, index, wad); } diff --git a/test/LockstakeEngine-invariants.t.sol b/test/LockstakeEngine-invariants.t.sol index 4466cf4..855fa91 100644 --- a/test/LockstakeEngine-invariants.t.sol +++ b/test/LockstakeEngine-invariants.t.sol @@ -9,10 +9,10 @@ import { LockstakeMkr } from "src/LockstakeMkr.sol"; import { PipMock } from "test/mocks/PipMock.sol"; import { VoteDelegateFactoryMock, VoteDelegateMock } from "test/mocks/VoteDelegateMock.sol"; import { GemMock } from "test/mocks/GemMock.sol"; -import { NstMock } from "test/mocks/NstMock.sol"; -import { NstJoinMock } from "test/mocks/NstJoinMock.sol"; +import { UsdsMock } from "test/mocks/UsdsMock.sol"; +import { UsdsJoinMock } from "test/mocks/UsdsJoinMock.sol"; import { StakingRewardsMock } from "test/mocks/StakingRewardsMock.sol"; -import { MkrNgtMock } from "test/mocks/MkrNgtMock.sol"; +import { MkrSkyMock } from "test/mocks/MkrSkyMock.sol"; import { LockstakeHandler } from "test/handlers/LockstakeHandler.sol"; interface ChainlogLike { @@ -67,14 +67,14 @@ contract LockstakeEngineIntegrationTest is DssTest { LockstakeClipper public clip; PipMock public pip; VoteDelegateFactoryMock public delFactory; - NstMock public nst; - NstJoinMock public nstJoin; + UsdsMock public usds; + UsdsJoinMock public usdsJoin; LockstakeMkr public lsmkr; GemMock public rTok; StakingRewardsMock public farm0; StakingRewardsMock public farm1; - MkrNgtMock public mkrNgt; - GemMock public ngt; + MkrSkyMock public mkrSky; + GemMock public sky; bytes32 public ilk = "LSE"; address public voter0; address public voter1; @@ -108,14 +108,14 @@ contract LockstakeEngineIntegrationTest is DssTest { dog = DogLike(ChainlogLike(LOG).getAddress("MCD_DOG")); mkr = new GemMock(0); jug = ChainlogLike(LOG).getAddress("MCD_JUG"); - nst = new NstMock(); - nstJoin = new NstJoinMock(address(vat), address(nst)); + usds = new UsdsMock(); + usdsJoin = new UsdsJoinMock(address(vat), address(usds)); lsmkr = new LockstakeMkr(); rTok = new GemMock(0); farm0 = new StakingRewardsMock(address(rTok), address(lsmkr)); farm1 = new StakingRewardsMock(address(rTok), address(lsmkr)); - ngt = new GemMock(0); - mkrNgt = new MkrNgtMock(address(mkr), address(ngt), 25_000); + sky = new GemMock(0); + mkrSky = new MkrSkyMock(address(mkr), address(sky), 25_000); pip = new PipMock(); delFactory = new VoteDelegateFactoryMock(address(mkr)); @@ -125,7 +125,7 @@ contract LockstakeEngineIntegrationTest is DssTest { vm.prank(voter1); voterDelegate1 = delFactory.create(); vm.startPrank(pauseProxy); - engine = new LockstakeEngine(address(delFactory), address(nstJoin), ilk, address(mkrNgt), address(lsmkr)); + engine = new LockstakeEngine(address(delFactory), address(usdsJoin), ilk, address(mkrSky), address(lsmkr)); engine.file("jug", jug); engine.file("fee", 15 * WAD / 100); vat.rely(address(engine)); @@ -169,10 +169,10 @@ contract LockstakeEngineIntegrationTest is DssTest { lsmkr.rely(address(engine)); deal(address(mkr), address(this), 100_000 * 10**18, true); - deal(address(ngt), address(this), 100_000 * 25_000 * 10**18, true); + deal(address(sky), address(this), 100_000 * 25_000 * 10**18, true); - // Add some existing DAI assigned to nstJoin to avoid a particular error - stdstore.target(address(vat)).sig("dai(address)").with_key(address(nstJoin)).depth(0).checked_write(100_000 * RAD); + // Add some existing DAI assigned to usdsJoin to avoid a particular error + stdstore.target(address(vat)).sig("dai(address)").with_key(address(usdsJoin)).depth(0).checked_write(100_000 * RAD); address[] memory voteDelegates = new address[](2); voteDelegates[0] = voterDelegate0; @@ -267,9 +267,9 @@ contract LockstakeEngineIntegrationTest is DssTest { console.log("selectFarm", handler.numCalls("selectFarm")); console.log("selectVoteDelegate", handler.numCalls("selectVoteDelegate")); console.log("lock", handler.numCalls("lock")); - console.log("lockNgt", handler.numCalls("lockNgt")); + console.log("lockSky", handler.numCalls("lockSky")); console.log("free", handler.numCalls("free")); - console.log("freeNgt", handler.numCalls("freeNgt")); + console.log("freeSky", handler.numCalls("freeSky")); console.log("draw", handler.numCalls("draw")); console.log("wipe", handler.numCalls("wipe")); console.log("dropPriceAndBark", handler.numCalls("dropPriceAndBark")); @@ -277,8 +277,8 @@ contract LockstakeEngineIntegrationTest is DssTest { console.log("yank", handler.numCalls("yank")); console.log("warp", handler.numCalls("warp")); console.log("total count", handler.numCalls("addFarm") + handler.numCalls("selectFarm") + handler.numCalls("selectVoteDelegate") + - handler.numCalls("lock") + handler.numCalls("lockNgt") + handler.numCalls("free") + - handler.numCalls("freeNgt") + handler.numCalls("draw") + handler.numCalls("wipe") + + handler.numCalls("lock") + handler.numCalls("lockSky") + handler.numCalls("free") + + handler.numCalls("freeSky") + handler.numCalls("draw") + handler.numCalls("wipe") + handler.numCalls("dropPriceAndBark") + handler.numCalls("take") + handler.numCalls("yank") + handler.numCalls("warp")); } diff --git a/test/LockstakeEngine.t.sol b/test/LockstakeEngine.t.sol index 97e007c..01d399b 100644 --- a/test/LockstakeEngine.t.sol +++ b/test/LockstakeEngine.t.sol @@ -12,10 +12,10 @@ import { LockstakeClipper } from "src/LockstakeClipper.sol"; import { LockstakeUrn } from "src/LockstakeUrn.sol"; import { VoteDelegateFactoryMock, VoteDelegateMock } from "test/mocks/VoteDelegateMock.sol"; import { GemMock } from "test/mocks/GemMock.sol"; -import { NstMock } from "test/mocks/NstMock.sol"; -import { NstJoinMock } from "test/mocks/NstJoinMock.sol"; +import { UsdsMock } from "test/mocks/UsdsMock.sol"; +import { UsdsJoinMock } from "test/mocks/UsdsJoinMock.sol"; import { StakingRewardsMock } from "test/mocks/StakingRewardsMock.sol"; -import { MkrNgtMock } from "test/mocks/MkrNgtMock.sol"; +import { MkrSkyMock } from "test/mocks/MkrSkyMock.sol"; interface CalcFabLike { function newLinearDecrease(address) external returns (address); @@ -41,13 +41,13 @@ contract LockstakeEngineTest is DssTest { address calc; MedianAbstract pip; VoteDelegateFactoryMock voteDelegateFactory; - NstMock nst; - NstJoinMock nstJoin; + UsdsMock usds; + UsdsJoinMock usdsJoin; GemMock rTok; StakingRewardsMock farm; StakingRewardsMock farm2; - MkrNgtMock mkrNgt; - GemMock ngt; + MkrSkyMock mkrSky; + GemMock sky; bytes32 ilk = "LSE"; address voter; address voteDelegate; @@ -66,9 +66,9 @@ contract LockstakeEngineTest is DssTest { event SelectVoteDelegate(address indexed owner, uint256 indexed index, address indexed voteDelegate_); event SelectFarm(address indexed owner, uint256 indexed index, address indexed farm, uint16 ref); event Lock(address indexed owner, uint256 indexed index, uint256 wad, uint16 ref); - event LockNgt(address indexed owner, uint256 indexed index, uint256 ngtWad, uint16 ref); + event LockSky(address indexed owner, uint256 indexed index, uint256 skyWad, uint16 ref); event Free(address indexed owner, uint256 indexed index, address to, uint256 wad, uint256 freed); - event FreeNgt(address indexed owner, uint256 indexed index, address to, uint256 ngtWad, uint256 ngtFreed); + event FreeSky(address indexed owner, uint256 indexed index, address to, uint256 skyWad, uint256 skyFreed); event FreeNoFee(address indexed owner, uint256 indexed index, address to, uint256 wad); event Draw(address indexed owner, uint256 indexed index, address to, uint256 wad); event Wipe(address indexed owner, uint256 indexed index, uint256 wad); @@ -92,13 +92,13 @@ contract LockstakeEngineTest is DssTest { pauseProxy = dss.chainlog.getAddress("MCD_PAUSE_PROXY"); pip = MedianAbstract(dss.chainlog.getAddress("PIP_MKR")); mkr = DSTokenAbstract(dss.chainlog.getAddress("MCD_GOV")); - nst = new NstMock(); - nstJoin = new NstJoinMock(address(dss.vat), address(nst)); + usds = new UsdsMock(); + usdsJoin = new UsdsJoinMock(address(dss.vat), address(usds)); rTok = new GemMock(0); - ngt = new GemMock(0); - mkrNgt = new MkrNgtMock(address(mkr), address(ngt), 24_000); + sky = new GemMock(0); + mkrSky = new MkrSkyMock(address(mkr), address(sky), 24_000); vm.startPrank(pauseProxy); - MkrAuthorityLike(mkr.authority()).rely(address(mkrNgt)); + MkrAuthorityLike(mkr.authority()).rely(address(mkrSky)); vm.stopPrank(); voteDelegateFactory = new VoteDelegateFactoryMock(address(mkr)); @@ -112,9 +112,9 @@ contract LockstakeEngineTest is DssTest { address(this), pauseProxy, address(voteDelegateFactory), - address(nstJoin), + address(usdsJoin), ilk, - address(mkrNgt), + address(mkrSky), bytes4(abi.encodeWithSignature("newLinearDecrease(address)")) ); @@ -132,11 +132,11 @@ contract LockstakeEngineTest is DssTest { cfg = LockstakeConfig({ ilk: ilk, voteDelegateFactory: address(voteDelegateFactory), - nstJoin: address(nstJoin), - nst: address(nstJoin.nst()), + usdsJoin: address(usdsJoin), + usds: address(usdsJoin.usds()), mkr: address(mkr), - mkrNgt: address(mkrNgt), - ngt: address(ngt), + mkrSky: address(mkrSky), + sky: address(sky), farms: farms, fee: 15 * WAD / 100, maxLine: 10_000_000 * 10**45, @@ -169,10 +169,10 @@ contract LockstakeEngineTest is DssTest { vm.stopPrank(); deal(address(mkr), address(this), 100_000 * 10**18, true); - deal(address(ngt), address(this), 100_000 * 24_000 * 10**18, true); + deal(address(sky), address(this), 100_000 * 24_000 * 10**18, true); - // Add some existing DAI assigned to nstJoin to avoid a particular error - stdstore.target(address(dss.vat)).sig("dai(address)").with_key(address(nstJoin)).depth(0).checked_write(100_000 * RAD); + // Add some existing DAI assigned to usdsJoin to avoid a particular error + stdstore.target(address(dss.vat)).sig("dai(address)").with_key(address(usdsJoin)).depth(0).checked_write(100_000 * RAD); } function _ink(bytes32 ilk_, address urn) internal view returns (uint256 ink) { @@ -230,14 +230,14 @@ contract LockstakeEngineTest is DssTest { function testDeployAndInit() public { assertEq(address(engine.voteDelegateFactory()), address(voteDelegateFactory)); assertEq(address(engine.vat()), address(dss.vat)); - assertEq(address(engine.nstJoin()), address(nstJoin)); - assertEq(address(engine.nst()), address(nst)); + assertEq(address(engine.usdsJoin()), address(usdsJoin)); + assertEq(address(engine.usds()), address(usds)); assertEq(engine.ilk(), ilk); assertEq(address(engine.mkr()), address(mkr)); assertEq(engine.fee(), 15 * WAD / 100); - assertEq(address(engine.mkrNgt()), address(mkrNgt)); - assertEq(address(engine.ngt()), address(ngt)); - assertEq(engine.mkrNgtRate(), 24_000); + assertEq(address(engine.mkrSky()), address(mkrSky)); + assertEq(address(engine.sky()), address(sky)); + assertEq(engine.mkrSkyRate(), 24_000); assertEq(LockstakeUrn(engine.urnImplementation()).engine(), address(engine)); assertEq(address(LockstakeUrn(engine.urnImplementation()).vat()), address(dss.vat)); assertEq(address(LockstakeUrn(engine.urnImplementation()).lsmkr()), address(lsmkr)); @@ -321,9 +321,9 @@ contract LockstakeEngineTest is DssTest { address(this), pauseProxy, address(voteDelegateFactory), - address(nstJoin), + address(usdsJoin), "eee", - address(mkrNgt), + address(mkrSky), bytes4(abi.encodeWithSignature("newStairstepExponentialDecrease(address)")) ); cfg.ilk = "eee"; @@ -343,24 +343,24 @@ contract LockstakeEngineTest is DssTest { address lsmkr2 = address(new GemMock(0)); vm.expectEmit(true, true, true, true); emit Rely(address(this)); - LockstakeEngine e = new LockstakeEngine(address(voteDelegateFactory), address(nstJoin), "aaa", address(mkrNgt), lsmkr2); + LockstakeEngine e = new LockstakeEngine(address(voteDelegateFactory), address(usdsJoin), "aaa", address(mkrSky), lsmkr2); assertEq(address(e.voteDelegateFactory()), address(voteDelegateFactory)); - assertEq(address(e.nstJoin()), address(nstJoin)); + assertEq(address(e.usdsJoin()), address(usdsJoin)); assertEq(address(e.vat()), address(dss.vat)); - assertEq(address(e.nst()), address(nst)); + assertEq(address(e.usds()), address(usds)); assertEq(e.ilk(), "aaa"); assertEq(address(e.mkr()), address(mkr)); assertEq(address(e.lsmkr()), lsmkr2); - assertEq(address(e.mkrNgt()), address(mkrNgt)); - assertEq(address(e.ngt()), address(ngt)); - assertEq(e.mkrNgtRate(), 24_000); + assertEq(address(e.mkrSky()), address(mkrSky)); + assertEq(address(e.sky()), address(sky)); + assertEq(e.mkrSkyRate(), 24_000); assertEq(LockstakeUrn(e.urnImplementation()).engine(), address(e)); assertEq(address(LockstakeUrn(e.urnImplementation()).vat()), address(dss.vat)); assertEq(address(LockstakeUrn(e.urnImplementation()).lsmkr()), lsmkr2); - assertEq(dss.vat.can(address(e), address(nstJoin)), 1); - assertEq(nst.allowance(address(e), address(nstJoin)), type(uint256).max); - assertEq(ngt.allowance(address(e), address(mkrNgt)), type(uint256).max); - assertEq(mkr.allowance(address(e), address(mkrNgt)), type(uint256).max); + assertEq(dss.vat.can(address(e), address(usdsJoin)), 1); + assertEq(usds.allowance(address(e), address(usdsJoin)), type(uint256).max); + assertEq(sky.allowance(address(e), address(mkrSky)), type(uint256).max); + assertEq(mkr.allowance(address(e), address(mkrSky)), type(uint256).max); assertEq(e.wards(address(this)), 1); } @@ -456,11 +456,11 @@ contract LockstakeEngineTest is DssTest { vm.expectRevert("LockstakeEngine/invalid-urn"); engine.lock(address(this), 1, 1, 1); vm.expectRevert("LockstakeEngine/invalid-urn"); - engine.lockNgt(address(this), 1, 1, 1); + engine.lockSky(address(this), 1, 1, 1); vm.expectRevert("LockstakeEngine/invalid-urn"); engine.free(address(this), 1, address(123), 1); vm.expectRevert("LockstakeEngine/invalid-urn"); - engine.freeNgt(address(this), 1, address(123), 1); + engine.freeSky(address(this), 1, address(123), 1); vm.expectRevert("LockstakeEngine/invalid-urn"); vm.prank(pauseProxy); engine.freeNoFee(address(this), 1, address(123), 1); vm.expectRevert("LockstakeEngine/invalid-urn"); @@ -487,7 +487,7 @@ contract LockstakeEngineTest is DssTest { vm.expectRevert("LockstakeEngine/urn-not-authorized"); engine.free(address(123), 0, address(123), 1); vm.expectRevert("LockstakeEngine/urn-not-authorized"); - engine.freeNgt(address(123), 0, address(123), 1); + engine.freeSky(address(123), 0, address(123), 1); vm.expectRevert("LockstakeEngine/urn-not-authorized"); vm.prank(pauseProxy); engine.freeNoFee(address(123), 0, address(123), 1); vm.expectRevert("LockstakeEngine/urn-not-authorized"); @@ -504,7 +504,7 @@ contract LockstakeEngineTest is DssTest { engine.rely(authedAndUrnAuthed); vm.stopPrank(); mkr.transfer(urnAuthed, 100_000 * 10**18); - ngt.transfer(urnAuthed, 100_000 * 24_000 * 10**18); + sky.transfer(urnAuthed, 100_000 * 24_000 * 10**18); vm.startPrank(urnOwner); address urn = engine.open(0); assertTrue(engine.isUrnAuth(urnOwner, 0, urnOwner)); @@ -526,15 +526,15 @@ contract LockstakeEngineTest is DssTest { assertEq(_ink(ilk, urn), 100_000 * 10**18); engine.free(urnOwner, 0, address(this), 50_000 * 10**18); assertEq(_ink(ilk, urn), 50_000 * 10**18); - ngt.approve(address(engine), 100_000 * 24_000 * 10**18); - engine.lockNgt(urnOwner, 0, 100_000 * 24_000 * 10**18, 0); + sky.approve(address(engine), 100_000 * 24_000 * 10**18); + engine.lockSky(urnOwner, 0, 100_000 * 24_000 * 10**18, 0); assertEq(_ink(ilk, urn), 150_000 * 10**18); - engine.freeNgt(urnOwner, 0, address(this), 50_000 * 24_000 * 10**18); + engine.freeSky(urnOwner, 0, address(this), 50_000 * 24_000 * 10**18); assertEq(_ink(ilk, urn), 100_000 * 10**18); engine.selectVoteDelegate(urnOwner, 0, voteDelegate); assertEq(engine.urnVoteDelegates(urn), voteDelegate); engine.draw(urnOwner, 0, address(urnAuthed), 1); - nst.approve(address(engine), 1); + usds.approve(address(engine), 1); engine.wipe(urnOwner, 0, 1); engine.selectFarm(urnOwner, 0, address(farm), 0); engine.getReward(urnOwner, 0, address(farm), address(0)); @@ -719,10 +719,10 @@ contract LockstakeEngineTest is DssTest { _testLockFree(true, true); } - function _testLockFreeNgt(bool withDelegate, bool withStaking) internal { - uint256 initialNgtSupply = ngt.totalSupply(); + function _testLockFreeSky(bool withDelegate, bool withStaking) internal { + uint256 initialSkySupply = sky.totalSupply(); address urn = engine.open(0); - // Note: overflow cannot be reached for lockNgt and freeNgt as with these functions and the value of rate (>=3) the MKR amount will be always lower + // Note: overflow cannot be reached for lockSky and freeSky as with these functions and the value of rate (>=3) the MKR amount will be always lower if (withDelegate) { engine.selectVoteDelegate(address(this), 0, voteDelegate); } @@ -731,10 +731,10 @@ contract LockstakeEngineTest is DssTest { } assertEq(_ink(ilk, urn), 0); assertEq(lsmkr.balanceOf(urn), 0); - ngt.approve(address(engine), 100_000 * 24_000 * 10**18); + sky.approve(address(engine), 100_000 * 24_000 * 10**18); vm.expectEmit(true, true, true, true); - emit LockNgt(address(this), 0, 100_000 * 24_000 * 10**18, 5); - engine.lockNgt(address(this), 0, 100_000 * 24_000 * 10**18, 5); + emit LockSky(address(this), 0, 100_000 * 24_000 * 10**18, 5); + engine.lockSky(address(this), 0, 100_000 * 24_000 * 10**18, 5); assertEq(_ink(ilk, urn), 100_000 * 10**18); if (withStaking) { assertEq(lsmkr.balanceOf(address(farm)), 100_000 * 10**18); @@ -742,17 +742,17 @@ contract LockstakeEngineTest is DssTest { } else { assertEq(lsmkr.balanceOf(urn), 100_000 * 10**18); } - assertEq(ngt.balanceOf(address(this)), 0); + assertEq(sky.balanceOf(address(this)), 0); if (withDelegate) { assertEq(mkr.balanceOf(address(engine)), 0); assertEq(mkr.balanceOf(voteDelegate), 100_000 * 10**18); // Remains in voteDelegate as it is a mock (otherwise it would be in the Chief) } else { assertEq(mkr.balanceOf(address(engine)), 100_000 * 10**18); } - assertEq(ngt.totalSupply(), initialNgtSupply - 100_000 * 24_000 * 10**18); + assertEq(sky.totalSupply(), initialSkySupply - 100_000 * 24_000 * 10**18); vm.expectEmit(true, true, true, true); - emit FreeNgt(address(this), 0, address(this), 40_000 * 24_000 * 10**18, 40_000 * 24_000 * 10**18 * 85 / 100); - assertEq(engine.freeNgt(address(this), 0, address(this), 40_000 * 24_000 * 10**18), 40_000 * 24_000 * 10**18 * 85 / 100); + emit FreeSky(address(this), 0, address(this), 40_000 * 24_000 * 10**18, 40_000 * 24_000 * 10**18 * 85 / 100); + assertEq(engine.freeSky(address(this), 0, address(this), 40_000 * 24_000 * 10**18), 40_000 * 24_000 * 10**18 * 85 / 100); assertEq(_ink(ilk, urn), 60_000 * 10**18); if (withStaking) { assertEq(lsmkr.balanceOf(address(farm)), 60_000 * 10**18); @@ -760,7 +760,7 @@ contract LockstakeEngineTest is DssTest { } else { assertEq(lsmkr.balanceOf(urn), 60_000 * 10**18); } - assertEq(ngt.balanceOf(address(this)), 40_000 * 24_000 * 10**18 - 40_000 * 24_000 * 10**18 * 15 / 100); + assertEq(sky.balanceOf(address(this)), 40_000 * 24_000 * 10**18 - 40_000 * 24_000 * 10**18 * 15 / 100); if (withDelegate) { assertEq(mkr.balanceOf(address(engine)), 0); assertEq(mkr.balanceOf(voteDelegate), 60_000 * 10**18); @@ -768,8 +768,8 @@ contract LockstakeEngineTest is DssTest { assertEq(mkr.balanceOf(address(engine)), 60_000 * 10**18); } vm.expectEmit(true, true, true, true); - emit FreeNgt(address(this), 0, address(123), 10_000 * 24_000 * 10**18, 10_000 * 24_000 * 10**18 * 85 / 100); - assertEq(engine.freeNgt(address(this), 0, address(123), 10_000 * 24_000 * 10**18), 10_000 * 24_000 * 10**18 * 85 / 100); + emit FreeSky(address(this), 0, address(123), 10_000 * 24_000 * 10**18, 10_000 * 24_000 * 10**18 * 85 / 100); + assertEq(engine.freeSky(address(this), 0, address(123), 10_000 * 24_000 * 10**18), 10_000 * 24_000 * 10**18 * 85 / 100); assertEq(_ink(ilk, urn), 50_000 * 10**18); if (withStaking) { assertEq(lsmkr.balanceOf(address(farm)), 50_000 * 10**18); @@ -777,36 +777,36 @@ contract LockstakeEngineTest is DssTest { } else { assertEq(lsmkr.balanceOf(urn), 50_000 * 10**18); } - assertEq(ngt.balanceOf(address(123)), 10_000 * 24_000 * 10**18 - 10_000 * 24_000 * 10**18 * 15 / 100); + assertEq(sky.balanceOf(address(123)), 10_000 * 24_000 * 10**18 - 10_000 * 24_000 * 10**18 * 15 / 100); if (withDelegate) { assertEq(mkr.balanceOf(address(engine)), 0); assertEq(mkr.balanceOf(voteDelegate), 50_000 * 10**18); } else { assertEq(mkr.balanceOf(address(engine)), 50_000 * 10**18); } - assertEq(ngt.totalSupply(), initialNgtSupply - (100_000 - 50_000) * 24_000 * 10**18 - 50_000 * 24_000 * 10**18 * 15 / 100); + assertEq(sky.totalSupply(), initialSkySupply - (100_000 - 50_000) * 24_000 * 10**18 - 50_000 * 24_000 * 10**18 * 15 / 100); if (withStaking) { - ngt.approve(address(engine), 24_000); + sky.approve(address(engine), 24_000); vm.prank(pauseProxy); engine.delFarm(address(farm)); vm.expectRevert("LockstakeEngine/farm-deleted"); - engine.lockNgt(address(this), 0, 24_000, 0); + engine.lockSky(address(this), 0, 24_000, 0); } } - function testLockFreeNgtNoDelegateNoStaking() public { - _testLockFreeNgt(false, false); + function testLockFreeSkyNoDelegateNoStaking() public { + _testLockFreeSky(false, false); } - function testLockFreeNgtWithDelegateNoStaking() public { - _testLockFreeNgt(true, false); + function testLockFreeSkyWithDelegateNoStaking() public { + _testLockFreeSky(true, false); } - function testLockFreeNgtNoDelegateWithStaking() public { - _testLockFreeNgt(false, true); + function testLockFreeSkyNoDelegateWithStaking() public { + _testLockFreeSky(false, true); } - function testLockFreeNgtWithDelegateWithStaking() public { - _testLockFreeNgt(true, true); + function testLockFreeSkyWithDelegateWithStaking() public { + _testLockFreeSky(true, true); } function _testFreeNoFee(bool withDelegate, bool withStaking) internal { @@ -903,7 +903,7 @@ contract LockstakeEngineTest is DssTest { engine.draw(address(this), 0, address(this), 50 * 10**18); assertEq(_art(ilk, urn), 50 * 10**18); assertEq(_rate(ilk), 10**27); - assertEq(nst.balanceOf(address(this)), 50 * 10**18); + assertEq(usds.balanceOf(address(this)), 50 * 10**18); vm.warp(block.timestamp + 1); vm.expectEmit(true, true, true, true); emit Draw(address(this), 0, address(this), 50 * 10**18); @@ -913,39 +913,39 @@ contract LockstakeEngineTest is DssTest { assertEq(art, expectedArt); uint256 rate = _rate(ilk); assertEq(rate, 100000001 * 10**27 / 100000000); - assertEq(nst.balanceOf(address(this)), 100 * 10**18); + assertEq(usds.balanceOf(address(this)), 100 * 10**18); assertGt(art * rate, 100.0000005 * 10**45); assertLt(art * rate, 100.0000006 * 10**45); - vm.expectRevert("Nst/insufficient-balance"); + vm.expectRevert("Usds/insufficient-balance"); engine.wipe(address(this), 0, 100.0000006 * 10**18); address anyone = address(1221121); - deal(address(nst), anyone, 100.0000006 * 10**18, true); - assertEq(nst.balanceOf(anyone), 100.0000006 * 10**18); - vm.prank(anyone); nst.approve(address(engine), 100.0000006 * 10**18); + deal(address(usds), anyone, 100.0000006 * 10**18, true); + assertEq(usds.balanceOf(anyone), 100.0000006 * 10**18); + vm.prank(anyone); usds.approve(address(engine), 100.0000006 * 10**18); vm.expectRevert(); vm.prank(anyone); engine.wipe(address(this), 0, 100.0000006 * 10**18); // It will try to wipe more art than existing, then reverts vm.expectEmit(true, true, true, true); emit Wipe(address(this), 0, 100.0000005 * 10**18); vm.prank(anyone); engine.wipe(address(this), 0, 100.0000005 * 10**18); - assertEq(nst.balanceOf(anyone), 0.0000001 * 10**18); + assertEq(usds.balanceOf(anyone), 0.0000001 * 10**18); assertEq(_art(ilk, urn), 1); // Dust which is impossible to wipe via this regular function emit Wipe(address(this), 0, _divup(rate, RAY)); vm.prank(anyone); assertEq(engine.wipeAll(address(this), 0), _divup(rate, RAY)); assertEq(_art(ilk, urn), 0); - assertEq(nst.balanceOf(anyone), 0.0000001 * 10**18 - _divup(rate, RAY)); + assertEq(usds.balanceOf(anyone), 0.0000001 * 10**18 - _divup(rate, RAY)); address other = address(123); - assertEq(nst.balanceOf(other), 0); + assertEq(usds.balanceOf(other), 0); emit Draw(address(this), 0, other, 50 * 10**18); engine.draw(address(this), 0, other, 50 * 10**18); - assertEq(nst.balanceOf(other), 50 * 10**18); + assertEq(usds.balanceOf(other), 50 * 10**18); // Check overflows stdstore.target(address(dss.vat)).sig("ilks(bytes32)").with_key(ilk).depth(1).checked_write(1); assertEq(_rate(ilk), 1); vm.expectRevert("LockstakeEngine/overflow"); engine.draw(address(this), 0, address(this), uint256(type(int256).max) / RAY + 1); - stdstore.target(address(dss.vat)).sig("dai(address)").with_key(address(nstJoin)).depth(0).checked_write(uint256(type(int256).max) + RAY); - deal(address(nst), address(this), uint256(type(int256).max) / RAY + 1, true); - nst.approve(address(engine), uint256(type(int256).max) / RAY + 1); + stdstore.target(address(dss.vat)).sig("dai(address)").with_key(address(usdsJoin)).depth(0).checked_write(uint256(type(int256).max) + RAY); + deal(address(usds), address(this), uint256(type(int256).max) / RAY + 1, true); + usds.approve(address(engine), uint256(type(int256).max) / RAY + 1); vm.expectRevert("LockstakeEngine/overflow"); engine.wipe(address(this), 0, uint256(type(int256).max) / RAY + 1); stdstore.target(address(dss.vat)).sig("urns(bytes32,address)").with_key(ilk).with_key(urn).depth(1).checked_write(uint256(type(int256).max) + 1); diff --git a/test/handlers/LockstakeHandler.sol b/test/handlers/LockstakeHandler.sol index 1ab601c..6e0068e 100644 --- a/test/handlers/LockstakeHandler.sol +++ b/test/handlers/LockstakeHandler.sol @@ -38,8 +38,8 @@ contract LockstakeHandler is StdUtils, StdCheats { LockstakeEngine public engine; GemMock public mkr; - GemMock public ngt; - GemMock public nst; + GemMock public sky; + GemMock public usds; bytes32 public ilk; VatLike public vat; JugLike public jug; @@ -53,7 +53,7 @@ contract LockstakeHandler is StdUtils, StdCheats { address public urn; address[] public voteDelegates; address[] public farms; - uint256 public mkrNgtRate; + uint256 public mkrSkyRate; address public anyone = address(123); mapping(bytes32 => uint256) public numCalls; @@ -92,8 +92,8 @@ contract LockstakeHandler is StdUtils, StdCheats { vm = vm_; engine = LockstakeEngine(engine_); mkr = GemMock(address(engine.mkr())); - ngt = GemMock(address(engine.ngt())); - nst = GemMock(address(engine.nst())); + sky = GemMock(address(engine.sky())); + usds = GemMock(address(engine.usds())); pauseProxy = pauseProxy_; ilk = engine.ilk(); vat = VatLike(address(engine.vat())); @@ -106,7 +106,7 @@ contract LockstakeHandler is StdUtils, StdCheats { owner = owner_; index = index_; urn = engine.ownerUrns(owner, index); - mkrNgtRate = engine.mkrNgtRate(); + mkrSkyRate = engine.mkrSkyRate(); vat.hope(address(clip)); @@ -230,25 +230,25 @@ contract LockstakeHandler is StdUtils, StdCheats { engine.lock(owner, index, wad, ref); } - function lockNgt(uint256 ngtWad, uint16 ref) external callAsAnyone { - numCalls["lockNgt"]++; + function lockSky(uint256 skyWad, uint16 ref) external callAsAnyone { + numCalls["lockSky"]++; - // ngtWad = bound(ngtWad, 0, uint256(type(int256).max) / 10**18) * 10**18; + // skyWad = bound(skyWad, 0, uint256(type(int256).max) / 10**18) * 10**18; (uint256 ink,) = vat.urns(ilk, urn); (,, uint256 spotPrice,,) = vat.ilks(ilk); - ngtWad = bound(ngtWad, 0, _min( + skyWad = bound(skyWad, 0, _min( uint256(type(int256).max), _min( type(uint256).max / spotPrice - ink, - type(uint256).max / mkrNgtRate + type(uint256).max / mkrSkyRate ) ) / 10**18 - ) * 10**18 * mkrNgtRate; + ) * 10**18 * mkrSkyRate; - deal(address(ngt), anyone, ngtWad); - ngt.approve(address(engine), ngtWad); + deal(address(sky), anyone, skyWad); + sky.approve(address(engine), skyWad); - engine.lockNgt(owner, index, ngtWad, ref); + engine.lockSky(owner, index, skyWad, ref); } function free(address to, uint256 wad) external callAsUrnOwner() { @@ -263,14 +263,14 @@ contract LockstakeHandler is StdUtils, StdCheats { engine.free(owner, index, to, wad); } - function freeNgt(address to, uint256 ngtWad) external callAsUrnOwner() { - numCalls["freeNgt"]++; + function freeSky(address to, uint256 skyWad) external callAsUrnOwner() { + numCalls["freeSky"]++; (uint256 ink, uint256 art ) = vat.urns(ilk, urn); (, uint256 rate, uint256 spotPrice,,) = vat.ilks(ilk); - ngtWad = bound(ngtWad, 0, (ink - _divup(art * rate, spotPrice)) * mkrNgtRate); + skyWad = bound(skyWad, 0, (ink - _divup(art * rate, spotPrice)) * mkrSkyRate); - engine.freeNgt(owner, index, to, ngtWad); + engine.freeSky(owner, index, to, skyWad); } function draw(uint256 wad) external callAsUrnOwner() { @@ -303,8 +303,8 @@ contract LockstakeHandler is StdUtils, StdCheats { ) : 0); - deal(address(nst), anyone, wad); - nst.approve(address(engine), wad); + deal(address(usds), anyone, wad); + usds.approve(address(engine), wad); engine.wipe(owner, index, wad); } diff --git a/test/mocks/MkrNgtMock.sol b/test/mocks/MkrNgtMock.sol deleted file mode 100644 index a0700e3..0000000 --- a/test/mocks/MkrNgtMock.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.21; - -interface GemLike { - function burn(address, uint256) external; - function mint(address, uint256) external; -} - -contract MkrNgtMock { - GemLike public immutable mkr; - GemLike public immutable ngt; - uint256 public immutable rate; - - constructor(address mkr_, address ngt_, uint256 rate_) { - mkr = GemLike(mkr_); - ngt = GemLike(ngt_); - rate = rate_; - } - - function mkrToNgt(address usr, uint256 mkrAmt) external { - mkr.burn(msg.sender, mkrAmt); - uint256 ngtAmt = mkrAmt * rate; - ngt.mint(usr, ngtAmt); - } - - function ngtToMkr(address usr, uint256 ngtAmt) external { - ngt.burn(msg.sender, ngtAmt); - uint256 mkrAmt = ngtAmt / rate; - mkr.mint(usr, mkrAmt); - } -} diff --git a/test/mocks/MkrSkyMock.sol b/test/mocks/MkrSkyMock.sol new file mode 100644 index 0000000..f86c054 --- /dev/null +++ b/test/mocks/MkrSkyMock.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.21; + +interface GemLike { + function burn(address, uint256) external; + function mint(address, uint256) external; +} + +contract MkrSkyMock { + GemLike public immutable mkr; + GemLike public immutable sky; + uint256 public immutable rate; + + constructor(address mkr_, address sky_, uint256 rate_) { + mkr = GemLike(mkr_); + sky = GemLike(sky_); + rate = rate_; + } + + function mkrToSky(address usr, uint256 mkrAmt) external { + mkr.burn(msg.sender, mkrAmt); + uint256 skyAmt = mkrAmt * rate; + sky.mint(usr, skyAmt); + } + + function skyToMkr(address usr, uint256 skyAmt) external { + sky.burn(msg.sender, skyAmt); + uint256 mkrAmt = skyAmt / rate; + mkr.mint(usr, mkrAmt); + } +} diff --git a/test/mocks/NstJoinMock.sol b/test/mocks/UsdsJoinMock.sol similarity index 67% rename from test/mocks/NstJoinMock.sol rename to test/mocks/UsdsJoinMock.sol index 5c3f25f..6ab21bb 100644 --- a/test/mocks/NstJoinMock.sol +++ b/test/mocks/UsdsJoinMock.sol @@ -8,22 +8,22 @@ interface VatLike { function move(address, address, uint256) external; } -contract NstJoinMock { +contract UsdsJoinMock { VatLike public vat; - GemMock public nst; + GemMock public usds; - constructor(address vat_, address nst_) { - vat = VatLike(vat_); - nst = GemMock(nst_); + constructor(address vat_, address usds_) { + vat = VatLike(vat_); + usds = GemMock(usds_); } function join(address usr, uint256 wad) external { vat.move(address(this), usr, wad * 10**27); - nst.burn(msg.sender, wad); + usds.burn(msg.sender, wad); } function exit(address usr, uint256 wad) external { vat.move(msg.sender, address(this), wad * 10**27); - nst.mint(usr, wad); + usds.mint(usr, wad); } } diff --git a/test/mocks/NstMock.sol b/test/mocks/UsdsMock.sol similarity index 84% rename from test/mocks/NstMock.sol rename to test/mocks/UsdsMock.sol index a5bf615..45bcdc1 100644 --- a/test/mocks/NstMock.sol +++ b/test/mocks/UsdsMock.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.21; -contract NstMock { +contract UsdsMock { mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; @@ -19,7 +19,7 @@ contract NstMock { function transfer(address to, uint256 value) external returns (bool) { uint256 balance = balanceOf[msg.sender]; - require(balance >= value, "Nst/insufficient-balance"); + require(balance >= value, "Usds/insufficient-balance"); unchecked { balanceOf[msg.sender] = balance - value; @@ -30,12 +30,12 @@ contract NstMock { function transferFrom(address from, address to, uint256 value) external returns (bool) { uint256 balance = balanceOf[from]; - require(balance >= value, "Nst/insufficient-balance"); + require(balance >= value, "Usds/insufficient-balance"); if (from != msg.sender) { uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { - require(allowed >= value, "Nst/insufficient-allowance"); + require(allowed >= value, "Usds/insufficient-allowance"); unchecked { allowance[from][msg.sender] = allowed - value; @@ -59,12 +59,12 @@ contract NstMock { function burn(address from, uint256 value) external { uint256 balance = balanceOf[from]; - require(balance >= value, "Nst/insufficient-balance"); + require(balance >= value, "Usds/insufficient-balance"); if (from != msg.sender) { uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { - require(allowed >= value, "Nst/insufficient-allowance"); + require(allowed >= value, "Usds/insufficient-allowance"); unchecked { allowance[from][msg.sender] = allowed - value;