diff --git a/.github/workflows/certora.yml b/.github/workflows/certora.yml index 3a3d436..f003e8a 100644 --- a/.github/workflows/certora.yml +++ b/.github/workflows/certora.yml @@ -9,9 +9,9 @@ jobs: strategy: fail-fast: false matrix: - ngt: - - ngt - - mkr-ngt + sky: + - sky + - mkr-sky steps: - name: Checkout @@ -37,7 +37,7 @@ jobs: - name: Install Certora run: pip3 install certora-cli - - name: Verify ${{ matrix.ngt }} - run: make certora-${{ matrix.ngt }} + - name: Verify ${{ matrix.sky }} + run: make certora-${{ matrix.sky }} env: CERTORAKEY: ${{ secrets.CERTORAKEY }} diff --git a/Makefile b/Makefile index 3a9e817..54f6b4d 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,3 @@ PATH := ~/.solc-select/artifacts/solc-0.8.21:~/.solc-select/artifacts:$(PATH) -certora-ngt :; PATH=${PATH} certoraRun certora/Ngt.conf$(if $(rule), --rule $(rule),) -certora-mkr-ngt :; PATH=${PATH} certoraRun certora/MkrNgt.conf$(if $(rule), --rule $(rule),) +certora-sky :; PATH=${PATH} certoraRun certora/Sky.conf$(if $(rule), --rule $(rule),) +certora-mkr-sky :; PATH=${PATH} certoraRun certora/MkrSky.conf$(if $(rule), --rule $(rule),) diff --git a/README.md b/README.md index 2c48d1f..642bb70 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ -# NGT Token and contract associated +# SKY Token and contract associated This repository includes 2 smart contracts: -- NGT token -- MkrNgt Converter +- SKY token +- MkrSky Converter -### NGT token +### SKY token This is a standard erc20 implementation with regular `permit` functionality + EIP-1271 smart contract signature validation. -In principle `PauseProxy` and `MkrNgt` would be the only two contracts set as `wards(address)`. +In principle `PauseProxy` and `MkrSky` would be the only two contracts set as `wards(address)`. -### MkrNgt +### MkrSky -It is a converter between `Mkr` and `Ngt` (both ways). Using the `mint` and `burn` capabilities of both tokens it is possible to exchange one to the other. The exchange rate is 1:`rate` (value defined as `immutable`). +It is a converter between `Mkr` and `Sky` (both ways). Using the `mint` and `burn` capabilities of both tokens it is possible to exchange one to the other. The exchange rate is 1:`rate` (value defined as `immutable`). **Note:** if one of the tokens removes `mint` capabilities to this contract, it means that the path which gives that token to the user won't be available. -**Note 2:** In the MKR -> NGT conversion, if the user passes a `wad` amount not multiple of `rate`, it causes that a dusty value will be lost. +**Note 2:** In the MKR -> SKY conversion, if the user passes a `wad` amount not multiple of `rate`, it causes that a dusty value will be lost. diff --git a/certora/MkrMock.sol b/certora/MkrMock.sol index 4452901..d94612d 100644 --- a/certora/MkrMock.sol +++ b/certora/MkrMock.sol @@ -1,7 +1,7 @@ pragma solidity ^0.8.21; -import "../src/Ngt.sol"; +import "../src/Sky.sol"; -contract MkrMock is Ngt { +contract MkrMock is Sky { } diff --git a/certora/MkrNgt.conf b/certora/MkrSky.conf similarity index 63% rename from certora/MkrNgt.conf rename to certora/MkrSky.conf index f5a3380..a4a1688 100644 --- a/certora/MkrNgt.conf +++ b/certora/MkrSky.conf @@ -1,21 +1,21 @@ { "files": [ - "src/MkrNgt.sol", - "src/Ngt.sol", + "src/MkrSky.sol", + "src/Sky.sol", "certora/MkrMock.sol" ], "link": [ - "MkrNgt:ngt=Ngt", - "MkrNgt:mkr=MkrMock" + "MkrSky:sky=Sky", + "MkrSky:mkr=MkrMock" ], "rule_sanity": "basic", "solc": "solc-0.8.21", "solc_optimize_map": { - "MkrNgt": "200", - "Ngt": "200", + "MkrSky": "200", + "Sky": "200", "MkrMock": "0" }, - "verify": "MkrNgt:certora/MkrNgt.spec", + "verify": "MkrSky:certora/MkrSky.spec", "prover_args": [ "-mediumTimeout 180" ], diff --git a/certora/MkrNgt.spec b/certora/MkrSky.spec similarity index 50% rename from certora/MkrNgt.spec rename to certora/MkrSky.spec index 4cdff31..0e9ec0a 100644 --- a/certora/MkrNgt.spec +++ b/certora/MkrSky.spec @@ -1,29 +1,29 @@ -// MkrNgt.spec +// MkrSky.spec -using Ngt as ngt; +using Sky as sky; using MkrMock as mkr; methods { function rate() external returns (uint256) envfree; - function ngt.wards(address) external returns (uint256) envfree; - function ngt.totalSupply() external returns (uint256) envfree; - function ngt.balanceOf(address) external returns (uint256) envfree; - function ngt.allowance(address, address) external returns (uint256) envfree; + function sky.wards(address) external returns (uint256) envfree; + function sky.totalSupply() external returns (uint256) envfree; + function sky.balanceOf(address) external returns (uint256) envfree; + function sky.allowance(address, address) external returns (uint256) envfree; function mkr.wards(address) external returns (uint256) envfree; function mkr.totalSupply() external returns (uint256) envfree; function mkr.balanceOf(address) external returns (uint256) envfree; function mkr.allowance(address, address) external returns (uint256) envfree; } -ghost balanceSumNgt() returns mathint { - init_state axiom balanceSumNgt() == 0; +ghost balanceSumSky() returns mathint { + init_state axiom balanceSumSky() == 0; } -hook Sstore ngt.balanceOf[KEY address a] uint256 balance (uint256 old_balance) { - havoc balanceSumNgt assuming balanceSumNgt@new() == balanceSumNgt@old() + balance - old_balance && balanceSumNgt@new() >= 0; +hook Sstore sky.balanceOf[KEY address a] uint256 balance (uint256 old_balance) { + havoc balanceSumSky assuming balanceSumSky@new() == balanceSumSky@old() + balance - old_balance && balanceSumSky@new() >= 0; } -invariant balanceSumNgt_equals_totalSupply() balanceSumNgt() == to_mathint(ngt.totalSupply()); +invariant balanceSumSky_equals_totalSupply() balanceSumSky() == to_mathint(sky.totalSupply()); ghost balanceSumMkr() returns mathint { init_state axiom balanceSumMkr() == 0; @@ -35,13 +35,13 @@ hook Sstore mkr.balanceOf[KEY address a] uint256 balance (uint256 old_balance) { invariant balanceSumMkr_equals_totalSupply() balanceSumMkr() == to_mathint(mkr.totalSupply()); -// Verify correct storage changes for non reverting mkrToNgt -rule mkrToNgt(address usr, uint256 wad) { +// Verify correct storage changes for non reverting mkrToSky +rule mkrToSky(address usr, uint256 wad) { env e; require e.msg.sender != currentContract; - requireInvariant balanceSumNgt_equals_totalSupply(); + requireInvariant balanceSumSky_equals_totalSupply(); requireInvariant balanceSumMkr_equals_totalSupply(); address other; @@ -50,53 +50,53 @@ rule mkrToNgt(address usr, uint256 wad) { require other2 != e.msg.sender; mathint rate = rate(); - mathint ngtTotalSupplyBefore = ngt.totalSupply(); - mathint ngtBalanceOfUsrBefore = ngt.balanceOf(usr); - mathint ngtBalanceOfOtherBefore = ngt.balanceOf(other); + mathint skyTotalSupplyBefore = sky.totalSupply(); + mathint skyBalanceOfUsrBefore = sky.balanceOf(usr); + mathint skyBalanceOfOtherBefore = sky.balanceOf(other); mathint mkrTotalSupplyBefore = mkr.totalSupply(); mathint mkrBalanceOfSenderBefore = mkr.balanceOf(e.msg.sender); mathint mkrBalanceOfOtherBefore = mkr.balanceOf(other2); - mkrToNgt(e, usr, wad); + mkrToSky(e, usr, wad); - mathint ngtTotalSupplyAfter = ngt.totalSupply(); - mathint ngtBalanceOfUsrAfter = ngt.balanceOf(usr); - mathint ngtBalanceOfOtherAfter = ngt.balanceOf(other); + mathint skyTotalSupplyAfter = sky.totalSupply(); + mathint skyBalanceOfUsrAfter = sky.balanceOf(usr); + mathint skyBalanceOfOtherAfter = sky.balanceOf(other); mathint mkrTotalSupplyAfter = mkr.totalSupply(); mathint mkrBalanceOfSenderAfter = mkr.balanceOf(e.msg.sender); mathint mkrBalanceOfOtherAfter = mkr.balanceOf(other2); - assert ngtTotalSupplyAfter == ngtTotalSupplyBefore + wad * rate, "mkrToNgt did not increase ngt.totalSupply by wad * rate"; - assert ngtBalanceOfUsrAfter == ngtBalanceOfUsrBefore + wad * rate, "mkrToNgt did not increase ngt.balanceOf[usr] by wad * rate"; - assert ngtBalanceOfOtherAfter == ngtBalanceOfOtherBefore, "mkrToNgt did not keep unchanged the rest of ngt.balanceOf[x]"; - assert mkrTotalSupplyAfter == mkrTotalSupplyBefore - wad, "mkrToNgt did not decrease mkr.totalSupply by wad"; - assert mkrBalanceOfSenderAfter == mkrBalanceOfSenderBefore - wad, "mkrToNgt did not decrease mkr.balanceOf[sender] by wad"; - assert mkrBalanceOfOtherAfter == mkrBalanceOfOtherBefore, "mkrToNgt did not keep unchanged the rest of mkr.balanceOf[x]"; + assert skyTotalSupplyAfter == skyTotalSupplyBefore + wad * rate, "mkrToSky did not increase sky.totalSupply by wad * rate"; + assert skyBalanceOfUsrAfter == skyBalanceOfUsrBefore + wad * rate, "mkrToSky did not increase sky.balanceOf[usr] by wad * rate"; + assert skyBalanceOfOtherAfter == skyBalanceOfOtherBefore, "mkrToSky did not keep unchanged the rest of sky.balanceOf[x]"; + assert mkrTotalSupplyAfter == mkrTotalSupplyBefore - wad, "mkrToSky did not decrease mkr.totalSupply by wad"; + assert mkrBalanceOfSenderAfter == mkrBalanceOfSenderBefore - wad, "mkrToSky did not decrease mkr.balanceOf[sender] by wad"; + assert mkrBalanceOfOtherAfter == mkrBalanceOfOtherBefore, "mkrToSky did not keep unchanged the rest of mkr.balanceOf[x]"; } -// Verify revert rules on mkrToNgt -rule mkrToNgt_revert(address usr, uint256 wad) { +// Verify revert rules on mkrToSky +rule mkrToSky_revert(address usr, uint256 wad) { env e; - requireInvariant balanceSumNgt_equals_totalSupply(); + requireInvariant balanceSumSky_equals_totalSupply(); requireInvariant balanceSumMkr_equals_totalSupply(); require e.msg.sender != currentContract; mathint rate = rate(); mathint mkrBalanceOfSender = mkr.balanceOf(e.msg.sender); - mathint mkrAllowanceSenderMkrNgt = mkr.allowance(e.msg.sender, currentContract); - mathint ngtWardsMkrNgt = ngt.wards(currentContract); - mathint ngtTotalSupply = ngt.totalSupply(); + mathint mkrAllowanceSenderMkrSky = mkr.allowance(e.msg.sender, currentContract); + mathint skyWardsMkrSky = sky.wards(currentContract); + mathint skyTotalSupply = sky.totalSupply(); - mkrToNgt@withrevert(e, usr, wad); + mkrToSky@withrevert(e, usr, wad); bool revert1 = e.msg.value > 0; bool revert2 = mkrBalanceOfSender < to_mathint(wad); - bool revert3 = mkrAllowanceSenderMkrNgt < to_mathint(wad); - bool revert4 = ngtWardsMkrNgt != 1; - bool revert5 = ngtTotalSupply + wad * rate > max_uint256; - bool revert6 = usr == 0 || usr == ngt; + bool revert3 = mkrAllowanceSenderMkrSky < to_mathint(wad); + bool revert4 = skyWardsMkrSky != 1; + bool revert5 = skyTotalSupply + wad * rate > max_uint256; + bool revert6 = usr == 0 || usr == sky; assert revert1 => lastReverted, "revert1 failed"; assert revert2 => lastReverted, "revert2 failed"; @@ -108,13 +108,13 @@ rule mkrToNgt_revert(address usr, uint256 wad) { revert4 || revert5 || revert6, "Revert rules are not covering all the cases"; } -// Verify correct storage changes for non reverting ngtToMkr -rule ngtToMkr(address usr, uint256 wad) { +// Verify correct storage changes for non reverting skyToMkr +rule skyToMkr(address usr, uint256 wad) { env e; require e.msg.sender != currentContract; - requireInvariant balanceSumNgt_equals_totalSupply(); + requireInvariant balanceSumSky_equals_totalSupply(); requireInvariant balanceSumMkr_equals_totalSupply(); address other; @@ -123,52 +123,52 @@ rule ngtToMkr(address usr, uint256 wad) { require other2 != usr; mathint rate = rate(); - mathint ngtTotalSupplyBefore = ngt.totalSupply(); - mathint ngtBalanceOfSenderBefore = ngt.balanceOf(e.msg.sender); - mathint ngtBalanceOfOtherBefore = ngt.balanceOf(other); + mathint skyTotalSupplyBefore = sky.totalSupply(); + mathint skyBalanceOfSenderBefore = sky.balanceOf(e.msg.sender); + mathint skyBalanceOfOtherBefore = sky.balanceOf(other); mathint mkrTotalSupplyBefore = mkr.totalSupply(); mathint mkrBalanceOfUsrBefore = mkr.balanceOf(usr); mathint mkrBalanceOfOtherBefore = mkr.balanceOf(other2); - ngtToMkr(e, usr, wad); + skyToMkr(e, usr, wad); - mathint ngtTotalSupplyAfter = ngt.totalSupply(); - mathint ngtBalanceOfSenderAfter = ngt.balanceOf(e.msg.sender); - mathint ngtBalanceOfOtherAfter = ngt.balanceOf(other); + mathint skyTotalSupplyAfter = sky.totalSupply(); + mathint skyBalanceOfSenderAfter = sky.balanceOf(e.msg.sender); + mathint skyBalanceOfOtherAfter = sky.balanceOf(other); mathint mkrTotalSupplyAfter = mkr.totalSupply(); mathint mkrBalanceOfUsrAfter = mkr.balanceOf(usr); mathint mkrBalanceOfOtherAfter = mkr.balanceOf(other2); - assert ngtTotalSupplyAfter == ngtTotalSupplyBefore - wad, "ngtToMkr did not decrease ngt.totalSupply by wad"; - assert ngtBalanceOfSenderAfter == ngtBalanceOfSenderBefore - wad, "ngtToMkr did not decrease ngt.balanceOf[sender] by wad"; - assert ngtBalanceOfOtherAfter == ngtBalanceOfOtherBefore, "ngtToMkr did not keep unchanged the rest of ngt.balanceOf[x]"; - assert mkrTotalSupplyAfter == mkrTotalSupplyBefore + wad / rate, "ngtToMkr did not increase mkr.totalSupply by wad / rate"; - assert mkrBalanceOfUsrAfter == mkrBalanceOfUsrBefore + wad / rate, "ngtToMkr did not increase mkr.balanceOf[usr] by wad / rate"; - assert mkrBalanceOfOtherAfter == mkrBalanceOfOtherBefore, "ngtToMkr did not keep unchanged the rest of mkr.balanceOf[x]"; + assert skyTotalSupplyAfter == skyTotalSupplyBefore - wad, "skyToMkr did not decrease sky.totalSupply by wad"; + assert skyBalanceOfSenderAfter == skyBalanceOfSenderBefore - wad, "skyToMkr did not decrease sky.balanceOf[sender] by wad"; + assert skyBalanceOfOtherAfter == skyBalanceOfOtherBefore, "skyToMkr did not keep unchanged the rest of sky.balanceOf[x]"; + assert mkrTotalSupplyAfter == mkrTotalSupplyBefore + wad / rate, "skyToMkr did not increase mkr.totalSupply by wad / rate"; + assert mkrBalanceOfUsrAfter == mkrBalanceOfUsrBefore + wad / rate, "skyToMkr did not increase mkr.balanceOf[usr] by wad / rate"; + assert mkrBalanceOfOtherAfter == mkrBalanceOfOtherBefore, "skyToMkr did not keep unchanged the rest of mkr.balanceOf[x]"; } -// Verify revert rules on ngtToMkr -rule ngtToMkr_revert(address usr, uint256 wad) { +// Verify revert rules on skyToMkr +rule skyToMkr_revert(address usr, uint256 wad) { env e; - requireInvariant balanceSumNgt_equals_totalSupply(); + requireInvariant balanceSumSky_equals_totalSupply(); requireInvariant balanceSumMkr_equals_totalSupply(); require e.msg.sender != currentContract; mathint rate = rate(); require rate > 0; - mathint ngtBalanceOfSender = ngt.balanceOf(e.msg.sender); - mathint ngtAllowanceSenderMkrNgt = ngt.allowance(e.msg.sender, currentContract); - mathint mkrWardsMkrNgt = mkr.wards(currentContract); + mathint skyBalanceOfSender = sky.balanceOf(e.msg.sender); + mathint skyAllowanceSenderMkrSky = sky.allowance(e.msg.sender, currentContract); + mathint mkrWardsMkrSky = mkr.wards(currentContract); mathint mkrTotalSupply = mkr.totalSupply(); - ngtToMkr@withrevert(e, usr, wad); + skyToMkr@withrevert(e, usr, wad); bool revert1 = e.msg.value > 0; - bool revert2 = ngtBalanceOfSender < to_mathint(wad); - bool revert3 = ngtAllowanceSenderMkrNgt < to_mathint(wad); - bool revert4 = mkrWardsMkrNgt != 1; + bool revert2 = skyBalanceOfSender < to_mathint(wad); + bool revert3 = skyAllowanceSenderMkrSky < to_mathint(wad); + bool revert4 = mkrWardsMkrSky != 1; bool revert5 = mkrTotalSupply + wad / rate > max_uint256; bool revert6 = usr == 0 || usr == mkr; diff --git a/certora/Ngt.conf b/certora/Sky.conf similarity index 82% rename from certora/Ngt.conf rename to certora/Sky.conf index 0728562..9e10106 100644 --- a/certora/Ngt.conf +++ b/certora/Sky.conf @@ -1,17 +1,17 @@ { "files": [ - "src/Ngt.sol", + "src/Sky.sol", "certora/Auxiliar.sol", "certora/SignerMock.sol" ], "rule_sanity": "basic", "solc": "solc-0.8.21", "solc_optimize_map": { - "Ngt": "200", + "Sky": "200", "Auxiliar": "0", "SignerMock": "0" }, - "verify": "Ngt:certora/Ngt.spec", + "verify": "Sky:certora/Sky.spec", "prover_args": [ "-mediumTimeout 180" ], diff --git a/certora/Ngt.spec b/certora/Sky.spec similarity index 99% rename from certora/Ngt.spec rename to certora/Sky.spec index 92ae8f6..ebc5e03 100644 --- a/certora/Ngt.spec +++ b/certora/Sky.spec @@ -1,4 +1,4 @@ -// Ngt.spec +// Sky.spec using Auxiliar as aux; using SignerMock as signer; diff --git a/deploy/NgtDeploy.sol b/deploy/SkyDeploy.sol similarity index 69% rename from deploy/NgtDeploy.sol rename to deploy/SkyDeploy.sol index 4a439d4..c66506e 100644 --- a/deploy/NgtDeploy.sol +++ b/deploy/SkyDeploy.sol @@ -18,24 +18,24 @@ pragma solidity ^0.8.21; import { ScriptTools } from "dss-test/ScriptTools.sol"; -import { Ngt } from "src/Ngt.sol"; -import { MkrNgt } from "src/MkrNgt.sol"; +import { Sky } from "src/Sky.sol"; +import { MkrSky } from "src/MkrSky.sol"; -import { NgtInstance } from "./NgtInstance.sol"; +import { SkyInstance } from "./SkyInstance.sol"; -library NgtDeploy { +library SkyDeploy { function deploy( address deployer, address owner, address mkr, uint256 rate - ) internal returns (NgtInstance memory instance) { - address _ngt = address(new Ngt()); - ScriptTools.switchOwner(_ngt, deployer, owner); + ) internal returns (SkyInstance memory instance) { + address _sky = address(new Sky()); + ScriptTools.switchOwner(_sky, deployer, owner); - address _mkrNgt = address(new MkrNgt(mkr, _ngt, rate)); + address _mkrSky = address(new MkrSky(mkr, _sky, rate)); - instance.ngt = _ngt; - instance.mkrNgt = _mkrNgt; + instance.sky = _sky; + instance.mkrSky = _mkrSky; } } diff --git a/deploy/NgtInit.sol b/deploy/SkyInit.sol similarity index 67% rename from deploy/NgtInit.sol rename to deploy/SkyInit.sol index c90be17..90dae83 100644 --- a/deploy/NgtInit.sol +++ b/deploy/SkyInit.sol @@ -17,15 +17,15 @@ pragma solidity >=0.8.0; import { DssInstance } from "dss-test/MCD.sol"; -import { NgtInstance } from "./NgtInstance.sol"; +import { SkyInstance } from "./SkyInstance.sol"; -interface NgtLike { +interface SkyLike { function rely(address) external; } -interface MkrNgtLike { +interface MkrSkyLike { function mkr() external view returns (address); - function ngt() external view returns (address); + function sky() external view returns (address); function rate() external view returns (uint256); } @@ -37,21 +37,21 @@ interface MkrAuthorityLike { function rely(address) external; } -library NgtInit { +library SkyInit { function init( DssInstance memory dss, - NgtInstance memory instance, + SkyInstance memory instance, uint256 rate ) internal { address mkr = dss.chainlog.getAddress("MCD_GOV"); - require(MkrNgtLike(instance.mkrNgt).mkr() == mkr, "NgtInit/mkr-does-not-match"); - require(MkrNgtLike(instance.mkrNgt).ngt() == instance.ngt, "NgtInit/ngt-does-not-match"); - require(MkrNgtLike(instance.mkrNgt).rate() == rate, "NgtInit/rate-does-not-match"); + require(MkrSkyLike(instance.mkrSky).mkr() == mkr, "SkyInit/mkr-does-not-match"); + require(MkrSkyLike(instance.mkrSky).sky() == instance.sky, "SkyInit/sky-does-not-match"); + require(MkrSkyLike(instance.mkrSky).rate() == rate, "SkyInit/rate-does-not-match"); - NgtLike(instance.ngt).rely(instance.mkrNgt); - MkrAuthorityLike(MkrLike(mkr).authority()).rely(instance.mkrNgt); + SkyLike(instance.sky).rely(instance.mkrSky); + MkrAuthorityLike(MkrLike(mkr).authority()).rely(instance.mkrSky); - dss.chainlog.setAddress("NGT", instance.ngt); - dss.chainlog.setAddress("MKR_NGT", instance.mkrNgt); + dss.chainlog.setAddress("SKY", instance.sky); + dss.chainlog.setAddress("MKR_SKY", instance.mkrSky); } } diff --git a/deploy/NgtInstance.sol b/deploy/SkyInstance.sol similarity index 93% rename from deploy/NgtInstance.sol rename to deploy/SkyInstance.sol index 6d779e1..b724cde 100644 --- a/deploy/NgtInstance.sol +++ b/deploy/SkyInstance.sol @@ -16,7 +16,7 @@ pragma solidity >=0.8.0; -struct NgtInstance { - address ngt; - address mkrNgt; +struct SkyInstance { + address sky; + address mkrSky; } diff --git a/src/MkrNgt.sol b/src/MkrSky.sol similarity index 59% rename from src/MkrNgt.sol rename to src/MkrSky.sol index 96ed1df..3cb27d8 100644 --- a/src/MkrNgt.sol +++ b/src/MkrSky.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -/// MkrNgt.sol -- Mkr/Ngt Exchanger +/// MkrSky.sol -- Mkr/Sky Exchanger // Copyright (C) 2023 Dai Foundation // @@ -24,31 +24,31 @@ interface GemLike { function mint(address, uint256) external; } -contract MkrNgt { +contract MkrSky { GemLike public immutable mkr; - GemLike public immutable ngt; + GemLike public immutable sky; uint256 public immutable rate; - event MkrToNgt(address indexed caller, address indexed usr, uint256 mkrAmt, uint256 ngtAmt); - event NgtToMkr(address indexed caller, address indexed usr, uint256 ngtAmt, uint256 mkrAmt); + event MkrToSky(address indexed caller, address indexed usr, uint256 mkrAmt, uint256 skyAmt); + event SkyToMkr(address indexed caller, address indexed usr, uint256 skyAmt, uint256 mkrAmt); - constructor(address mkr_, address ngt_, uint256 rate_) { + constructor(address mkr_, address sky_, uint256 rate_) { mkr = GemLike(mkr_); - ngt = GemLike(ngt_); + sky = GemLike(sky_); rate = rate_; } - function mkrToNgt(address usr, uint256 mkrAmt) external { + function mkrToSky(address usr, uint256 mkrAmt) external { mkr.burn(msg.sender, mkrAmt); - uint256 ngtAmt = mkrAmt * rate; - ngt.mint(usr, ngtAmt); - emit MkrToNgt(msg.sender, usr, mkrAmt, ngtAmt); + uint256 skyAmt = mkrAmt * rate; + sky.mint(usr, skyAmt); + emit MkrToSky(msg.sender, usr, mkrAmt, skyAmt); } - function ngtToMkr(address usr, uint256 ngtAmt) external { - ngt.burn(msg.sender, ngtAmt); - uint256 mkrAmt = ngtAmt / rate; // Rounding down, dust will be lost if it is not multiple of rate + function skyToMkr(address usr, uint256 skyAmt) external { + sky.burn(msg.sender, skyAmt); + uint256 mkrAmt = skyAmt / rate; // Rounding down, dust will be lost if it is not multiple of rate mkr.mint(usr, mkrAmt); - emit NgtToMkr(msg.sender, usr, ngtAmt, mkrAmt); + emit SkyToMkr(msg.sender, usr, skyAmt, mkrAmt); } } diff --git a/src/Ngt.sol b/src/Sky.sol similarity index 88% rename from src/Ngt.sol rename to src/Sky.sol index 28dd28c..4f405e4 100644 --- a/src/Ngt.sol +++ b/src/Sky.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -/// Ngt.sol -- Ngt token +/// Sky.sol -- Sky token // Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico // Copyright (C) 2023 Dai Foundation @@ -27,12 +27,12 @@ interface IERC1271 { ) external view returns (bytes4); } -contract Ngt { +contract Sky { mapping (address => uint256) public wards; // --- ERC20 Data --- - string public constant name = "NstDAO Governance Token"; - string public constant symbol = "NGT"; + string public constant name = "SKY Governance Token"; + string public constant symbol = "SKY"; string public constant version = "1"; uint8 public constant decimals = 18; uint256 public totalSupply; @@ -53,7 +53,7 @@ contract Ngt { bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); modifier auth { - require(wards[msg.sender] == 1, "Ngt/not-authorized"); + require(wards[msg.sender] == 1, "Sky/not-authorized"); _; } @@ -94,9 +94,9 @@ contract Ngt { // --- ERC20 Mutations --- function transfer(address to, uint256 value) external returns (bool) { - require(to != address(0) && to != address(this), "Ngt/invalid-address"); + require(to != address(0) && to != address(this), "Sky/invalid-address"); uint256 balance = balanceOf[msg.sender]; - require(balance >= value, "Ngt/insufficient-balance"); + require(balance >= value, "Sky/insufficient-balance"); unchecked { balanceOf[msg.sender] = balance - value; @@ -109,14 +109,14 @@ contract Ngt { } function transferFrom(address from, address to, uint256 value) external returns (bool) { - require(to != address(0) && to != address(this), "Ngt/invalid-address"); + require(to != address(0) && to != address(this), "Sky/invalid-address"); uint256 balance = balanceOf[from]; - require(balance >= value, "Ngt/insufficient-balance"); + require(balance >= value, "Sky/insufficient-balance"); if (from != msg.sender) { uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { - require(allowed >= value, "Ngt/insufficient-allowance"); + require(allowed >= value, "Sky/insufficient-allowance"); unchecked { allowance[from][msg.sender] = allowed - value; @@ -144,7 +144,7 @@ contract Ngt { // --- Mint/Burn --- function mint(address to, uint256 value) external auth { - require(to != address(0) && to != address(this), "Ngt/invalid-address"); + require(to != address(0) && to != address(this), "Sky/invalid-address"); unchecked { balanceOf[to] = balanceOf[to] + value; // note: we don't need an overflow check here b/c balanceOf[to] <= totalSupply and there is an overflow check below } @@ -155,12 +155,12 @@ contract Ngt { function burn(address from, uint256 value) external { uint256 balance = balanceOf[from]; - require(balance >= value, "Ngt/insufficient-balance"); + require(balance >= value, "Sky/insufficient-balance"); if (from != msg.sender) { uint256 allowed = allowance[from][msg.sender]; if (allowed != type(uint256).max) { - require(allowed >= value, "Ngt/insufficient-allowance"); + require(allowed >= value, "Sky/insufficient-allowance"); unchecked { allowance[from][msg.sender] = allowed - value; @@ -213,8 +213,8 @@ contract Ngt { uint256 deadline, bytes memory signature ) public { - require(block.timestamp <= deadline, "Ngt/permit-expired"); - require(owner != address(0), "Ngt/invalid-owner"); + require(block.timestamp <= deadline, "Sky/permit-expired"); + require(owner != address(0), "Sky/invalid-owner"); uint256 nonce; unchecked { nonce = nonces[owner]++; } @@ -233,7 +233,7 @@ contract Ngt { )) )); - require(_isValidSignature(owner, digest, signature), "Ngt/invalid-permit"); + require(_isValidSignature(owner, digest, signature), "Sky/invalid-permit"); allowance[owner][spender] = value; emit Approval(owner, spender, value); diff --git a/test/MkrNgt.t.sol b/test/MkrNgt.t.sol deleted file mode 100644 index 1e2924c..0000000 --- a/test/MkrNgt.t.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.21; - -import "dss-test/DssTest.sol"; - -import { Ngt } from "src/Ngt.sol"; -import { MkrNgt } from "src/MkrNgt.sol"; - -contract Mkr is Ngt {} - -contract MkrNgtTest is DssTest { - Mkr mkr; - Ngt ngt; - MkrNgt mkrNgt; - - event MkrToNgt(address indexed caller, address indexed usr, uint256 mkrAmt, uint256 ngtAmt); - event NgtToMkr(address indexed caller, address indexed usr, uint256 ngtAmt, uint256 mkrAmt); - - function setUp() public { - mkr = new Mkr(); - ngt = new Ngt(); - mkrNgt = new MkrNgt(address(mkr), address(ngt), 1200); - mkr.mint(address(this), 1_000_000 * WAD); - mkr.rely(address(mkrNgt)); - mkr.deny(address(this)); - ngt.rely(address(mkrNgt)); - ngt.deny(address(this)); - } - - function testExchange() public { - assertEq(mkr.balanceOf(address(this)), 1_000_000 * WAD); - assertEq(mkr.totalSupply(), 1_000_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 0); - assertEq(ngt.totalSupply(), 0); - - mkr.approve(address(mkrNgt), 400_000 * WAD); - vm.expectEmit(true, true, true, true); - emit MkrToNgt(address(this), address(this), 400_000 * WAD, 400_000 * WAD * 1200); - mkrNgt.mkrToNgt(address(this), 400_000 * WAD); - assertEq(mkr.balanceOf(address(this)), 600_000 * WAD); - assertEq(mkr.totalSupply(), 600_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 400_000 * WAD * 1200); - assertEq(ngt.totalSupply(), 400_000 * WAD * 1200); - - ngt.approve(address(mkrNgt), 200_000 * WAD * 1200); - vm.expectEmit(true, true, true, true); - emit NgtToMkr(address(this), address(this), 200_000 * WAD * 1200, 200_000 * WAD); - mkrNgt.ngtToMkr(address(this), 200_000 * WAD * 1200); - assertEq(mkr.balanceOf(address(this)), 800_000 * WAD); - assertEq(mkr.totalSupply(), 800_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 200_000 * WAD * 1200); - assertEq(ngt.totalSupply(), 200_000 * WAD * 1200); - - address receiver = address(123); - assertEq(mkr.balanceOf(receiver), 0); - assertEq(ngt.balanceOf(receiver), 0); - - mkr.approve(address(mkrNgt), 150_000 * WAD); - vm.expectEmit(true, true, true, true); - emit MkrToNgt(address(this), receiver, 150_000 * WAD, 150_000 * WAD * 1200); - mkrNgt.mkrToNgt(receiver, 150_000 * WAD); - assertEq(mkr.balanceOf(address(this)), 650_000 * WAD); - assertEq(mkr.balanceOf(receiver), 0); - assertEq(mkr.totalSupply(), 650_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 200_000 * WAD * 1200); - assertEq(ngt.balanceOf(receiver), 150_000 * WAD * 1200); - assertEq(ngt.totalSupply(), 350_000 * WAD * 1200); - - ngt.approve(address(mkrNgt), 50_000 * WAD * 1200); - vm.expectEmit(true, true, true, true); - emit NgtToMkr(address(this), receiver, 50_000 * WAD * 1200, 50_000 * WAD); - mkrNgt.ngtToMkr(receiver, 50_000 * WAD * 1200); - assertEq(mkr.balanceOf(address(this)), 650_000 * WAD); - assertEq(mkr.balanceOf(receiver), 50_000 * WAD); - assertEq(mkr.totalSupply(), 700_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 150_000 * WAD * 1200); - assertEq(ngt.balanceOf(receiver), 150_000 * WAD * 1200); - assertEq(ngt.totalSupply(), 300_000 * WAD * 1200); - - ngt.approve(address(mkrNgt), 50_000 * WAD * 1200 + 1199); - vm.expectEmit(true, true, true, true); - emit NgtToMkr(address(this), address(this), 50_000 * WAD * 1200 + 1199, 50_000 * WAD); - mkrNgt.ngtToMkr(address(this), 50_000 * WAD * 1200 + 1199); - assertEq(mkr.balanceOf(address(this)), 700_000 * WAD); - assertEq(mkr.balanceOf(receiver), 50_000 * WAD); - assertEq(mkr.totalSupply(), 750_000 * WAD); - assertEq(ngt.balanceOf(address(this)), 100_000 * WAD * 1200 - 1199); - assertEq(ngt.balanceOf(receiver), 150_000 * WAD * 1200); - assertEq(ngt.totalSupply(), 250_000 * WAD * 1200 - 1199); - } -} diff --git a/test/MkrSky.t.sol b/test/MkrSky.t.sol new file mode 100644 index 0000000..878b67b --- /dev/null +++ b/test/MkrSky.t.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.21; + +import "dss-test/DssTest.sol"; + +import { Sky } from "src/Sky.sol"; +import { MkrSky } from "src/MkrSky.sol"; + +contract Mkr is Sky {} + +contract MkrSkyTest is DssTest { + Mkr mkr; + Sky sky; + MkrSky mkrSky; + + event MkrToSky(address indexed caller, address indexed usr, uint256 mkrAmt, uint256 skyAmt); + event SkyToMkr(address indexed caller, address indexed usr, uint256 skyAmt, uint256 mkrAmt); + + function setUp() public { + mkr = new Mkr(); + sky = new Sky(); + mkrSky = new MkrSky(address(mkr), address(sky), 1200); + mkr.mint(address(this), 1_000_000 * WAD); + mkr.rely(address(mkrSky)); + mkr.deny(address(this)); + sky.rely(address(mkrSky)); + sky.deny(address(this)); + } + + function testExchange() public { + assertEq(mkr.balanceOf(address(this)), 1_000_000 * WAD); + assertEq(mkr.totalSupply(), 1_000_000 * WAD); + assertEq(sky.balanceOf(address(this)), 0); + assertEq(sky.totalSupply(), 0); + + mkr.approve(address(mkrSky), 400_000 * WAD); + vm.expectEmit(true, true, true, true); + emit MkrToSky(address(this), address(this), 400_000 * WAD, 400_000 * WAD * 1200); + mkrSky.mkrToSky(address(this), 400_000 * WAD); + assertEq(mkr.balanceOf(address(this)), 600_000 * WAD); + assertEq(mkr.totalSupply(), 600_000 * WAD); + assertEq(sky.balanceOf(address(this)), 400_000 * WAD * 1200); + assertEq(sky.totalSupply(), 400_000 * WAD * 1200); + + sky.approve(address(mkrSky), 200_000 * WAD * 1200); + vm.expectEmit(true, true, true, true); + emit SkyToMkr(address(this), address(this), 200_000 * WAD * 1200, 200_000 * WAD); + mkrSky.skyToMkr(address(this), 200_000 * WAD * 1200); + assertEq(mkr.balanceOf(address(this)), 800_000 * WAD); + assertEq(mkr.totalSupply(), 800_000 * WAD); + assertEq(sky.balanceOf(address(this)), 200_000 * WAD * 1200); + assertEq(sky.totalSupply(), 200_000 * WAD * 1200); + + address receiver = address(123); + assertEq(mkr.balanceOf(receiver), 0); + assertEq(sky.balanceOf(receiver), 0); + + mkr.approve(address(mkrSky), 150_000 * WAD); + vm.expectEmit(true, true, true, true); + emit MkrToSky(address(this), receiver, 150_000 * WAD, 150_000 * WAD * 1200); + mkrSky.mkrToSky(receiver, 150_000 * WAD); + assertEq(mkr.balanceOf(address(this)), 650_000 * WAD); + assertEq(mkr.balanceOf(receiver), 0); + assertEq(mkr.totalSupply(), 650_000 * WAD); + assertEq(sky.balanceOf(address(this)), 200_000 * WAD * 1200); + assertEq(sky.balanceOf(receiver), 150_000 * WAD * 1200); + assertEq(sky.totalSupply(), 350_000 * WAD * 1200); + + sky.approve(address(mkrSky), 50_000 * WAD * 1200); + vm.expectEmit(true, true, true, true); + emit SkyToMkr(address(this), receiver, 50_000 * WAD * 1200, 50_000 * WAD); + mkrSky.skyToMkr(receiver, 50_000 * WAD * 1200); + assertEq(mkr.balanceOf(address(this)), 650_000 * WAD); + assertEq(mkr.balanceOf(receiver), 50_000 * WAD); + assertEq(mkr.totalSupply(), 700_000 * WAD); + assertEq(sky.balanceOf(address(this)), 150_000 * WAD * 1200); + assertEq(sky.balanceOf(receiver), 150_000 * WAD * 1200); + assertEq(sky.totalSupply(), 300_000 * WAD * 1200); + + sky.approve(address(mkrSky), 50_000 * WAD * 1200 + 1199); + vm.expectEmit(true, true, true, true); + emit SkyToMkr(address(this), address(this), 50_000 * WAD * 1200 + 1199, 50_000 * WAD); + mkrSky.skyToMkr(address(this), 50_000 * WAD * 1200 + 1199); + assertEq(mkr.balanceOf(address(this)), 700_000 * WAD); + assertEq(mkr.balanceOf(receiver), 50_000 * WAD); + assertEq(mkr.totalSupply(), 750_000 * WAD); + assertEq(sky.balanceOf(address(this)), 100_000 * WAD * 1200 - 1199); + assertEq(sky.balanceOf(receiver), 150_000 * WAD * 1200); + assertEq(sky.totalSupply(), 250_000 * WAD * 1200 - 1199); + } +} diff --git a/test/Ngt.t.sol b/test/Ngt.t.sol deleted file mode 100644 index 50a0d7e..0000000 --- a/test/Ngt.t.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -pragma solidity ^0.8.21; - -import "token-tests/TokenFuzzTests.sol"; - -import { Ngt } from "src/Ngt.sol"; - -contract NgtTest is TokenFuzzTests { - Ngt ngt; - - function setUp() public { - vm.expectEmit(true, true, true, true); - emit Rely(address(this)); - ngt = new Ngt(); - - _token_ = address(ngt); - _contractName_ = "Ngt"; - _tokenName_ ="NstDAO Governance Token"; - _symbol_ = "NGT"; - } - - function invariantMetadata() public view { - assertEq(ngt.name(), "NstDAO Governance Token"); - assertEq(ngt.symbol(), "NGT"); - assertEq(ngt.version(), "1"); - assertEq(ngt.decimals(), 18); - } -} diff --git a/test/Sky.t.sol b/test/Sky.t.sol new file mode 100644 index 0000000..edb734b --- /dev/null +++ b/test/Sky.t.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +pragma solidity ^0.8.21; + +import "token-tests/TokenFuzzTests.sol"; + +import { Sky } from "src/Sky.sol"; + +contract SkyTest is TokenFuzzTests { + Sky sky; + + function setUp() public { + vm.expectEmit(true, true, true, true); + emit Rely(address(this)); + sky = new Sky(); + + _token_ = address(sky); + _contractName_ = "Sky"; + _tokenName_ = "SKY Governance Token"; + _symbol_ = "SKY"; + } + + function invariantMetadata() public view { + assertEq(sky.name(), "SKY Governance Token"); + assertEq(sky.symbol(), "SKY"); + assertEq(sky.version(), "1"); + assertEq(sky.decimals(), 18); + } +} diff --git a/test/integration/Deployment.t.sol b/test/integration/Deployment.t.sol index 4f915f1..a141def 100644 --- a/test/integration/Deployment.t.sol +++ b/test/integration/Deployment.t.sol @@ -18,12 +18,12 @@ pragma solidity ^0.8.21; import "dss-test/DssTest.sol"; -import { NgtInstance } from "deploy/NgtInstance.sol"; -import { NgtDeploy } from "deploy/NgtDeploy.sol"; -import { NgtInit, MkrLike } from "deploy/NgtInit.sol"; +import { SkyInstance } from "deploy/SkyInstance.sol"; +import { SkyDeploy } from "deploy/SkyDeploy.sol"; +import { SkyInit, MkrLike } from "deploy/SkyInit.sol"; -import { Ngt } from "src/Ngt.sol"; -import { MkrNgt } from "src/MkrNgt.sol"; +import { Sky } from "src/Sky.sol"; +import { MkrSky } from "src/MkrSky.sol"; interface ChainlogLike { function getAddress(bytes32) external view returns (address); @@ -44,7 +44,7 @@ contract DeploymentTest is DssTest { address PAUSE_PROXY; address MKR; - NgtInstance inst; + SkyInstance inst; function setUp() public { vm.createSelectFork(vm.envString("ETH_RPC_URL")); @@ -52,40 +52,40 @@ contract DeploymentTest is DssTest { PAUSE_PROXY = ChainlogLike(LOG).getAddress("MCD_PAUSE_PROXY"); MKR = ChainlogLike(LOG).getAddress("MCD_GOV"); - inst = NgtDeploy.deploy(address(this), PAUSE_PROXY, MKR, 1200); + inst = SkyDeploy.deploy(address(this), PAUSE_PROXY, MKR, 1200); } function testSetUp() public { DssInstance memory dss = MCD.loadFromChainlog(LOG); - assertEq(Ngt(inst.ngt).wards(inst.mkrNgt), 0); - assertEq(MkrAuthorityLike(MkrLike(MKR).authority()).wards(inst.mkrNgt), 0); + assertEq(Sky(inst.sky).wards(inst.mkrSky), 0); + assertEq(MkrAuthorityLike(MkrLike(MKR).authority()).wards(inst.mkrSky), 0); vm.startPrank(PAUSE_PROXY); - NgtInit.init(dss, inst, 1200); + SkyInit.init(dss, inst, 1200); vm.stopPrank(); - assertEq(Ngt(inst.ngt).wards(inst.mkrNgt), 1); - assertEq(MkrAuthorityLike(MkrLike(MKR).authority()).wards(inst.mkrNgt), 1); + assertEq(Sky(inst.sky).wards(inst.mkrSky), 1); + assertEq(MkrAuthorityLike(MkrLike(MKR).authority()).wards(inst.mkrSky), 1); deal(MKR, address(this), 1000); assertEq(GemLike(MKR).balanceOf(address(this)), 1000); - assertEq(GemLike(inst.ngt).balanceOf(address(this)), 0); + assertEq(GemLike(inst.sky).balanceOf(address(this)), 0); - GemLike(MKR).approve(inst.mkrNgt, 600); - MkrNgt(inst.mkrNgt).mkrToNgt(address(this), 600); + GemLike(MKR).approve(inst.mkrSky, 600); + MkrSky(inst.mkrSky).mkrToSky(address(this), 600); assertEq(GemLike(MKR).balanceOf(address(this)), 400); - assertEq(GemLike(inst.ngt).balanceOf(address(this)), 600 * 1200); + assertEq(GemLike(inst.sky).balanceOf(address(this)), 600 * 1200); - GemLike(inst.ngt).approve(inst.mkrNgt, 400 * 1200); - MkrNgt(inst.mkrNgt).ngtToMkr(address(this), 400 * 1200); + GemLike(inst.sky).approve(inst.mkrSky, 400 * 1200); + MkrSky(inst.mkrSky).skyToMkr(address(this), 400 * 1200); assertEq(GemLike(MKR).balanceOf(address(this)), 800); - assertEq(GemLike(inst.ngt).balanceOf(address(this)), 200 * 1200); + assertEq(GemLike(inst.sky).balanceOf(address(this)), 200 * 1200); - assertEq(ChainlogLike(LOG).getAddress("NGT"), inst.ngt); - assertEq(ChainlogLike(LOG).getAddress("MKR_NGT"), inst.mkrNgt); + assertEq(ChainlogLike(LOG).getAddress("SKY"), inst.sky); + assertEq(ChainlogLike(LOG).getAddress("MKR_SKY"), inst.mkrSky); } }