diff --git a/README.md b/README.md
index 342886e4..ad05c34d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Multi Collateral Dai
+ # Multi Collateral Dai

This repository contains the core smart contract code for Multi
diff --git a/cache/solidity-files-cache.json b/cache/solidity-files-cache.json
new file mode 100644
index 00000000..048daecd
--- /dev/null
+++ b/cache/solidity-files-cache.json
@@ -0,0 +1 @@
+{"_format":"","paths":{"artifacts":"out","build_infos":"out/build-info","sources":"src","tests":"test","scripts":"script","libraries":["lib"]},"files":{"src/dai.sol":{"lastModificationDate":1782316029874,"contentHash":"fe8a705d06c13780","interfaceReprHash":null,"sourceName":"src/dai.sol","imports":[],"versionRequirement":"^0.8.0","artifacts":{"Dai":{"0.8.35":{"default":{"path":"dai.sol/Dai.json","build_id":"fd067ac922a9a6cb"}}}},"seenByCompiler":true}},"builds":["fd067ac922a9a6cb"],"profiles":{"default":{"solc":{"optimizer":{"enabled":false,"runs":200},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"outputSelection":{"*":{"*":["abi","evm.bytecode.object","evm.bytecode.sourceMap","evm.bytecode.linkReferences","evm.deployedBytecode.object","evm.deployedBytecode.sourceMap","evm.deployedBytecode.linkReferences","evm.deployedBytecode.immutableReferences","evm.methodIdentifiers","metadata"]}},"evmVersion":"osaka","viaIR":false,"libraries":{}},"vyper":{"evmVersion":"osaka","outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode"]}}}}},"preprocessed":false,"mocks":[]}
\ No newline at end of file
diff --git a/gas_report_dai.txt b/gas_report_dai.txt
new file mode 100644
index 00000000..76f40a6e
--- /dev/null
+++ b/gas_report_dai.txt
@@ -0,0 +1,152 @@
+No files changed, compilation skipped
+
+Ran 34 tests for src/test/dai.t.sol:DaiTest
+[PASS] testAllowanceStartsAtZero() (gas: 15515)
+Logs:
+ gas: 12982
+
+[PASS] testApproveSetsAllowance() (gas: 72741)
+Logs:
+ Test: 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496
+ Token: 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
+ Me: 0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496
+ User 2: 0xc7183455a4C133Ae270771860664b6B7ec320bB1
+ gas: 70121
+
+[PASS] testApproveWillModifyAllowance() (gas: 178489)
+[PASS] testApproveWillNotModifyAllowance() (gas: 165917)
+[PASS] testBurn() (gas: 43548)
+[PASS] testBurnAuth() (gas: 140739)
+[PASS] testBurnGuyAuth() (gas: 154865)
+[PASS] testBurnGuyWithTrust() (gas: 160494)
+[PASS] testBurnself() (gas: 46116)
+[PASS] testChargesAmountApproved() (gas: 121885)
+Logs:
+ gas: 124087
+
+[PASS] testDaiAddress() (gas: 14046)
+Logs:
+ Error: a == b not satisfied [address]
+ Expected: 0x11Ee1eeF5D446D07Cf26941C7F2B4B1Dfb9D030B
+ Actual: 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
+
+[PASS] testDomain_Separator() (gas: 19337)
+Logs:
+ Error: a == b not satisfied [bytes32]
+ Expected: 0x68a9504c1a7fba795f7730732abab11cb5fa5113edd2396392abd5c1bbda4043
+ Actual: 0xfad5514f651d156e6fe232ee8ae83a6cfca2d936832a0cece2737056c6446819
+
+[PASS] testMintGuy() (gas: 65522)
+[PASS] testMintGuyAuth() (gas: 119328)
+[PASS] testMintself() (gas: 48492)
+[PASS] testPermit() (gas: 147142)
+[PASS] testPermitWithExpiry() (gas: 123742)
+[PASS] testRevertChargeMoreThanApproved() (gas: 160642)
+Logs:
+ Error: Assertion Failed
+ gas: 158067
+
+[PASS] testRevertIfWrongAccountTransfers() (gas: 48209)
+Logs:
+ Error: Assertion Failed
+ gas: 45678
+
+[PASS] testRevertInsufficientFundsTransfers() (gas: 101028)
+Logs:
+ Error: Assertion Failed
+ gas: 98409
+
+[PASS] testRevertMintGuyNoAuth() (gas: 41221)
+[PASS] testRevertPermitAddress0() (gas: 44445)
+[PASS] testRevertPermitWithExpiry() (gas: 55199)
+[PASS] testRevertReplay() (gas: 148820)
+[PASS] testRevertTransferFromSelfNonArbitrarySize() (gas: 54403)
+Logs:
+ Error: Assertion Failed
+
+[PASS] testRevertTransferWithoutApproval() (gas: 104001)
+Logs:
+ Error: Assertion Failed
+ gas: 101450
+
+[PASS] testRevertUntrustedTransferFrom() (gas: 59692)
+[PASS] testSetupPrecondition() (gas: 10621)
+[PASS] testTransferCost() (gas: 60033)
+Logs:
+ gas: 57433
+
+[PASS] testTransferFromSelf() (gas: 66751)
+[PASS] testTrustedTransferFrom() (gas: 128249)
+[PASS] testTrusting() (gas: 108382)
+[PASS] testTypehash() (gas: 5843)
+[PASS] testValidTransfers() (gas: 79111)
+Logs:
+ token11111: 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
+ gas: 76510
+
+Suite result: ok. 34 passed; 0 failed; 0 skipped; finished in 129.05ms (124.97ms CPU time)
+
+╭--------------------------+-----------------+-------+--------+-------+---------╮
+| src/dai.sol:Dai Contract | | | | | |
++===============================================================================+
+| Deployment Cost | Deployment Size | | | | |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| 1429297 | 6935 | | | | |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| | | | | | |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| Function Name | Min | Avg | Median | Max | # Calls |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| DOMAIN_SEPARATOR | 2448 | 2448 | 2448 | 2448 | 4 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| PERMIT_TYPEHASH | 420 | 420 | 420 | 420 | 4 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| allowance | 3169 | 3169 | 3169 | 3169 | 15 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| approve | 24739 | 43681 | 46663 | 47023 | 7 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| balanceOf | 2891 | 2891 | 2891 | 2891 | 16 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| burn | 32022 | 33682 | 34512 | 34512 | 3 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| mint | 36910 | 62077 | 54010 | 71122 | 70 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| nonces | 2913 | 2913 | 2913 | 2913 | 3 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| permit | 28496 | 56032 | 58448 | 79198 | 6 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| rely | 46360 | 46360 | 46360 | 46360 | 2 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| totalSupply | 2470 | 2470 | 2470 | 2470 | 1 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| transfer | 24562 | 48974 | 52055 | 52067 | 9 |
+|--------------------------+-----------------+-------+--------+-------+---------|
+| transferFrom | 25097 | 31539 | 27463 | 52566 | 5 |
+╰--------------------------+-----------------+-------+--------+-------+---------╯
+
+╭---------------------------------------+-----------------+-------+--------+-------+---------╮
+| src/test/dai.t.sol:TokenUser Contract | | | | | |
++============================================================================================+
+| Deployment Cost | Deployment Size | | | | |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| 735260 | 3347 | | | | |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| | | | | | |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| Function Name | Min | Avg | Median | Max | # Calls |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doApprove(address) | 52656 | 52656 | 52656 | 52656 | 2 |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doApprove(address,uint256) | 52921 | 52921 | 52921 | 52921 | 1 |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doBurn(address,uint256) | 37980 | 37980 | 37980 | 37980 | 1 |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doBurn(uint256) | 35106 | 35106 | 35106 | 35106 | 1 |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doMint | 30644 | 45284 | 45284 | 59925 | 2 |
+|---------------------------------------+-----------------+-------+--------+-------+---------|
+| doTransferFrom | 33632 | 55286 | 59855 | 64667 | 5 |
+╰---------------------------------------+-----------------+-------+--------+-------+---------╯
+
+
+Ran 1 test suite in 233.85ms (129.05ms CPU time): 34 tests passed, 0 failed, 0 skipped (34 total tests)
diff --git a/src/abaci.sol b/src/abaci.sol
index 6cbd6662..7b5a1826 100644
--- a/src/abaci.sol
+++ b/src/abaci.sol
@@ -27,18 +27,25 @@ interface Abacus {
}
contract LinearDecrease is Abacus {
-
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "LinearDecrease/not-authorized");
_;
}
// --- Data ---
- uint256 public tau; // Seconds after auction start when the price reaches zero [seconds]
+ uint256 public tau; // Seconds after auction start when the price reaches zero [seconds]
// --- Events ---
event Rely(address indexed usr);
@@ -54,19 +61,22 @@ contract LinearDecrease is Abacus {
// --- Administration ---
function file(bytes32 what, uint256 data) external auth {
- if (what == "tau") tau = data;
+ if (what == "tau") tau = data;
else revert("LinearDecrease/file-unrecognized-param");
emit File(what, data);
}
// --- Math ---
uint256 constant RAY = 10 ** 27;
+
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
+
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
require(y == 0 || z / y == x);
@@ -82,26 +92,33 @@ contract LinearDecrease is Abacus {
//
// Note the internal call to mul multiples by RAY, thereby ensuring that the rmul calculation
// which utilizes top and tau (RAY values) is also a RAY value.
- function price(uint256 top, uint256 dur) override external view returns (uint256) {
+ function price(uint256 top, uint256 dur) external view override returns (uint256) {
if (dur >= tau) return 0;
return rmul(top, mul(tau - dur, RAY) / tau);
}
}
contract StairstepExponentialDecrease is Abacus {
-
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "StairstepExponentialDecrease/not-authorized");
_;
}
// --- Data ---
uint256 public step; // Length of time between price drops [seconds]
- uint256 public cut; // Per-step multiplicative factor [ray]
+ uint256 public cut; // Per-step multiplicative factor [ray]
// --- Events ---
event Rely(address indexed usr);
@@ -119,7 +136,7 @@ contract StairstepExponentialDecrease is Abacus {
// --- Administration ---
function file(bytes32 what, uint256 data) external auth {
- if (what == "cut") require((cut = data) <= RAY, "StairstepExponentialDecrease/cut-gt-RAY");
+ if (what == "cut") require((cut = data) <= RAY, "StairstepExponentialDecrease/cut-gt-RAY");
else if (what == "step") step = data;
else revert("StairstepExponentialDecrease/file-unrecognized-param");
emit File(what, data);
@@ -127,31 +144,37 @@ contract StairstepExponentialDecrease is Abacus {
// --- Math ---
uint256 constant RAY = 10 ** 27;
+
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
require(y == 0 || z / y == x);
z = z / RAY;
}
+
// optimized version from dss PR #78
function rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) {
assembly {
- switch n case 0 { z := b }
+ switch n
+ case 0 { z := b }
default {
- switch x case 0 { z := 0 }
+ switch x
+ case 0 { z := 0 }
default {
- switch mod(n, 2) case 0 { z := b } default { z := x }
- let half := div(b, 2) // for rounding.
- for { n := div(n, 2) } n { n := div(n,2) } {
+ switch mod(n, 2)
+ case 0 { z := b }
+ default { z := x }
+ let half := div(b, 2) // for rounding.
+ for { n := div(n, 2) } n { n := div(n, 2) } {
let xx := mul(x, x)
- if shr(128, x) { revert(0,0) }
+ if shr(128, x) { revert(0, 0) }
let xxRound := add(xx, half)
- if lt(xxRound, xx) { revert(0,0) }
+ if lt(xxRound, xx) { revert(0, 0) }
x := div(xxRound, b)
- if mod(n,2) {
+ if mod(n, 2) {
let zx := mul(z, x)
- if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
+ if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) }
let zxRound := add(zx, half)
- if lt(zxRound, zx) { revert(0,0) }
+ if lt(zxRound, zx) { revert(0, 0) }
z := div(zxRound, b)
}
}
@@ -170,7 +193,7 @@ contract StairstepExponentialDecrease is Abacus {
// returns: top * (cut ^ dur)
//
//
- function price(uint256 top, uint256 dur) override external view returns (uint256) {
+ function price(uint256 top, uint256 dur) external view override returns (uint256) {
return rmul(top, rpow(cut, dur / step, RAY));
}
}
@@ -179,18 +202,25 @@ contract StairstepExponentialDecrease is Abacus {
// this continous (i.e. per-second) exponential decrease has be implemented as it is more gas-efficient
// than using the stairstep version with step = 1 (primarily due to 1 fewer SLOAD per price calculation).
contract ExponentialDecrease is Abacus {
-
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "ExponentialDecrease/not-authorized");
_;
}
// --- Data ---
- uint256 public cut; // Per-second multiplicative factor [ray]
+ uint256 public cut; // Per-second multiplicative factor [ray]
// --- Events ---
event Rely(address indexed usr);
@@ -208,38 +238,44 @@ contract ExponentialDecrease is Abacus {
// --- Administration ---
function file(bytes32 what, uint256 data) external auth {
- if (what == "cut") require((cut = data) <= RAY, "ExponentialDecrease/cut-gt-RAY");
+ if (what == "cut") require((cut = data) <= RAY, "ExponentialDecrease/cut-gt-RAY");
else revert("ExponentialDecrease/file-unrecognized-param");
emit File(what, data);
}
// --- Math ---
uint256 constant RAY = 10 ** 27;
+
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
require(y == 0 || z / y == x);
z = z / RAY;
}
+
// optimized version from dss PR #78
function rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) {
assembly {
- switch n case 0 { z := b }
+ switch n
+ case 0 { z := b }
default {
- switch x case 0 { z := 0 }
+ switch x
+ case 0 { z := 0 }
default {
- switch mod(n, 2) case 0 { z := b } default { z := x }
- let half := div(b, 2) // for rounding.
- for { n := div(n, 2) } n { n := div(n,2) } {
+ switch mod(n, 2)
+ case 0 { z := b }
+ default { z := x }
+ let half := div(b, 2) // for rounding.
+ for { n := div(n, 2) } n { n := div(n, 2) } {
let xx := mul(x, x)
- if shr(128, x) { revert(0,0) }
+ if shr(128, x) { revert(0, 0) }
let xxRound := add(xx, half)
- if lt(xxRound, xx) { revert(0,0) }
+ if lt(xxRound, xx) { revert(0, 0) }
x := div(xxRound, b)
- if mod(n,2) {
+ if mod(n, 2) {
let zx := mul(z, x)
- if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
+ if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) }
let zxRound := add(zx, half)
- if lt(zxRound, zx) { revert(0,0) }
+ if lt(zxRound, zx) { revert(0, 0) }
z := div(zxRound, b)
}
}
@@ -256,7 +292,7 @@ contract ExponentialDecrease is Abacus {
//
// returns: top * (cut ^ dur)
//
- function price(uint256 top, uint256 dur) override external view returns (uint256) {
+ function price(uint256 top, uint256 dur) external view override returns (uint256) {
return rmul(top, rpow(cut, dur, RAY));
}
}
diff --git a/src/cat.sol b/src/cat.sol
index f359dbcc..a2667f18 100644
--- a/src/cat.sol
+++ b/src/cat.sol
@@ -24,23 +24,28 @@ pragma solidity >=0.5.12;
// New deployments of this contract will need to include custom events (TO DO).
interface Kicker {
- function kick(address urn, address gal, uint256 tab, uint256 lot, uint256 bid)
- external returns (uint256);
+ function kick(address urn, address gal, uint256 tab, uint256 lot, uint256 bid) external returns (uint256);
}
interface VatLike {
- function ilks(bytes32) external view returns (
- uint256 Art, // [wad]
- uint256 rate, // [ray]
- uint256 spot, // [ray]
- uint256 line, // [rad]
- uint256 dust // [rad]
- );
- function urns(bytes32,address) external view returns (
- uint256 ink, // [wad]
- uint256 art // [wad]
- );
- function grab(bytes32,address,address,address,int256,int256) external;
+ function ilks(bytes32)
+ external
+ view
+ returns (
+ uint256 Art, // [wad]
+ uint256 rate, // [ray]
+ uint256 spot, // [ray]
+ uint256 line, // [rad]
+ uint256 dust // [rad]
+ );
+ function urns(bytes32, address)
+ external
+ view
+ returns (
+ uint256 ink, // [wad]
+ uint256 art // [wad]
+ );
+ function grab(bytes32, address, address, address, int256, int256) external;
function hope(address) external;
function nope(address) external;
}
@@ -51,38 +56,38 @@ interface VowLike {
contract Cat {
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Cat/not-authorized");
_;
}
// --- Data ---
struct Ilk {
- address flip; // Liquidator
- uint256 chop; // Liquidation Penalty [wad]
- uint256 dunk; // Liquidation Quantity [rad]
+ address flip; // Liquidator
+ uint256 chop; // Liquidation Penalty [wad]
+ uint256 dunk; // Liquidation Quantity [rad]
}
- mapping (bytes32 => Ilk) public ilks;
+ mapping(bytes32 => Ilk) public ilks;
- uint256 public live; // Active Flag
- VatLike public vat; // CDP Engine
- VowLike public vow; // Debt Engine
- uint256 public box; // Max Dai out for liquidation [rad]
+ uint256 public live; // Active Flag
+ VatLike public vat; // CDP Engine
+ VowLike public vow; // Debt Engine
+ uint256 public box; // Max Dai out for liquidation [rad]
uint256 public litter; // Balance of Dai out for liquidation [rad]
// --- Events ---
event Bite(
- bytes32 indexed ilk,
- address indexed urn,
- uint256 ink,
- uint256 art,
- uint256 tab,
- address flip,
- uint256 id
+ bytes32 indexed ilk, address indexed urn, uint256 ink, uint256 art, uint256 tab, address flip, uint256 id
);
// --- Init ---
@@ -96,14 +101,18 @@ contract Cat {
uint256 constant WAD = 10 ** 18;
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
- if (x > y) { z = y; } else { z = x; }
+ if (x > y) z = y;
+ else z = x;
}
+
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
+
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -113,27 +122,31 @@ contract Cat {
if (what == "vow") vow = VowLike(data);
else revert("Cat/file-unrecognized-param");
}
+
function file(bytes32 what, uint256 data) external auth {
if (what == "box") box = data;
else revert("Cat/file-unrecognized-param");
}
+
function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
if (what == "chop") ilks[ilk].chop = data;
else if (what == "dunk") ilks[ilk].dunk = data;
else revert("Cat/file-unrecognized-param");
}
+
function file(bytes32 ilk, bytes32 what, address flip) external auth {
if (what == "flip") {
vat.nope(ilks[ilk].flip);
ilks[ilk].flip = flip;
vat.hope(flip);
+ } else {
+ revert("Cat/file-unrecognized-param");
}
- else revert("Cat/file-unrecognized-param");
}
// --- CDP Liquidation ---
function bite(bytes32 ilk, address urn) external returns (uint256 id) {
- (,uint256 rate,uint256 spot,,uint256 dust) = vat.ilks(ilk);
+ (, uint256 rate, uint256 spot,, uint256 dust) = vat.ilks(ilk);
(uint256 ink, uint256 art) = vat.urns(ilk, urn);
require(live == 1, "Cat/not-live");
@@ -152,13 +165,11 @@ contract Cat {
uint256 dink = min(ink, mul(ink, dart) / art);
- require(dart > 0 && dink > 0 , "Cat/null-auction");
- require(dart <= 2**255 && dink <= 2**255, "Cat/overflow" );
+ require(dart > 0 && dink > 0, "Cat/null-auction");
+ require(dart <= 2 ** 255 && dink <= 2 ** 255, "Cat/overflow");
// This may leave the CDP in a dusty state
- vat.grab(
- ilk, urn, address(this), address(vow), -int256(dink), -int256(dart)
- );
+ vat.grab(ilk, urn, address(this), address(vow), -int256(dink), -int256(dart));
vow.fess(mul(dart, rate));
{ // Avoid stack too deep
@@ -167,13 +178,7 @@ contract Cat {
uint256 tab = mul(mul(dart, rate), milk.chop) / WAD;
litter = add(litter, tab);
- id = Kicker(milk.flip).kick({
- urn: urn,
- gal: address(vow),
- tab: tab,
- lot: dink,
- bid: 0
- });
+ id = Kicker(milk.flip).kick({urn: urn, gal: address(vow), tab: tab, lot: dink, bid: 0});
}
emit Bite(ilk, urn, dink, dart, mul(dart, rate), milk.flip, id);
diff --git a/src/clip.sol b/src/clip.sol
index c43d8fff..2625dd48 100644
--- a/src/clip.sol
+++ b/src/clip.sol
@@ -20,10 +20,10 @@
pragma solidity ^0.6.12;
interface VatLike {
- function move(address,address,uint256) external;
- function flux(bytes32,address,address,uint256) external;
+ function move(address, address, uint256) external;
+ function flux(bytes32, address, address, uint256) external;
function ilks(bytes32) external returns (uint256, uint256, uint256, uint256, uint256);
- function suck(address,address,uint256) external;
+ function suck(address, address, uint256) external;
}
interface PipLike {
@@ -50,40 +50,48 @@ interface AbacusLike {
contract Clipper {
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Clipper/not-authorized");
_;
}
// --- Data ---
- bytes32 immutable public ilk; // Collateral type of this Clipper
- VatLike immutable public vat; // Core CDP Engine
+ bytes32 public immutable ilk; // Collateral type of this Clipper
+ VatLike public immutable vat; // Core CDP Engine
- DogLike public dog; // Liquidation module
- address public vow; // Recipient of dai raised in auctions
- SpotterLike public spotter; // Collateral price module
- AbacusLike public calc; // Current price calculator
+ DogLike public dog; // Liquidation module
+ address public vow; // Recipient of dai raised in auctions
+ SpotterLike public spotter; // Collateral price module
+ AbacusLike public calc; // Current price calculator
- uint256 public buf; // Multiplicative factor to increase starting price [ray]
- uint256 public tail; // Time elapsed before auction reset [seconds]
- uint256 public cusp; // Percentage drop before auction reset [ray]
- uint64 public chip; // Percentage of tab to suck from vow to incentivize keepers [wad]
- uint192 public tip; // Flat fee to suck from vow to incentivize keepers [rad]
- uint256 public chost; // Cache the ilk dust times the ilk chop to prevent excessive SLOADs [rad]
+ uint256 public buf; // Multiplicative factor to increase starting price [ray]
+ uint256 public tail; // Time elapsed before auction reset [seconds]
+ uint256 public cusp; // Percentage drop before auction reset [ray]
+ uint64 public chip; // Percentage of tab to suck from vow to incentivize keepers [wad]
+ uint192 public tip; // Flat fee to suck from vow to incentivize keepers [rad]
+ uint256 public chost; // Cache the ilk dust times the ilk chop to prevent excessive SLOADs [rad]
- uint256 public kicks; // Total auctions
- uint256[] public active; // Array of active auction ids
+ uint256 public kicks; // Total auctions
+ uint256[] public active; // Array of active auction ids
struct Sale {
- uint256 pos; // Index in active array
- uint256 tab; // Dai to raise [rad]
- uint256 lot; // collateral to sell [wad]
- address usr; // Liquidated CDP
- uint96 tic; // Auction start time
- uint256 top; // Starting price [ray]
+ uint256 pos; // Index in active array
+ uint256 tab; // Dai to raise [rad]
+ uint256 lot; // collateral to sell [wad]
+ address usr; // Liquidated CDP
+ uint96 tic; // Auction start time
+ uint256 top; // Starting price [ray]
}
mapping(uint256 => Sale) public sales;
@@ -113,13 +121,7 @@ contract Clipper {
uint256 coin
);
event Take(
- uint256 indexed id,
- uint256 max,
- uint256 price,
- uint256 owe,
- uint256 tab,
- uint256 lot,
- address indexed usr
+ uint256 indexed id, uint256 max, uint256 price, uint256 owe, uint256 tab, uint256 lot, address indexed usr
);
event Redo(
uint256 indexed id,
@@ -135,17 +137,17 @@ contract Clipper {
// --- Init ---
constructor(address vat_, address spotter_, address dog_, bytes32 ilk_) public {
- vat = VatLike(vat_);
+ vat = VatLike(vat_);
spotter = SpotterLike(spotter_);
- dog = DogLike(dog_);
- ilk = ilk_;
- buf = RAY;
+ dog = DogLike(dog_);
+ ilk = ilk_;
+ buf = RAY;
wards[msg.sender] = 1;
emit Rely(msg.sender);
}
// --- Synchronization ---
- modifier lock {
+ modifier lock() {
require(locked == 0, "Clipper/system-locked");
locked = 1;
_;
@@ -159,47 +161,54 @@ contract Clipper {
// --- Administration ---
function file(bytes32 what, uint256 data) external auth lock {
- if (what == "buf") buf = data;
- else if (what == "tail") tail = data; // Time elapsed before auction reset
- else if (what == "cusp") cusp = data; // Percentage drop before auction reset
- else if (what == "chip") chip = uint64(data); // Percentage of tab to incentivize (max: 2^64 - 1 => 18.xxx WAD = 18xx%)
- else if (what == "tip") tip = uint192(data); // Flat fee to incentivize keepers (max: 2^192 - 1 => 6.277T RAD)
- else if (what == "stopped") stopped = data; // Set breaker (0, 1, 2, or 3)
+ if (what == "buf") buf = data;
+ else if (what == "tail") tail = data; // Time elapsed before auction reset
+ else if (what == "cusp") cusp = data; // Percentage drop before auction reset
+ else if (what == "chip") chip = uint64(data); // Percentage of tab to incentivize (max: 2^64 - 1 => 18.xxx WAD = 18xx%)
+ else if (what == "tip") tip = uint192(data); // Flat fee to incentivize keepers (max: 2^192 - 1 => 6.277T RAD)
+ else if (what == "stopped") stopped = data; // Set breaker (0, 1, 2, or 3)
else revert("Clipper/file-unrecognized-param");
emit File(what, data);
}
+
function file(bytes32 what, address data) external auth lock {
if (what == "spotter") spotter = SpotterLike(data);
- else if (what == "dog") dog = DogLike(data);
- else if (what == "vow") vow = data;
- else if (what == "calc") calc = AbacusLike(data);
+ else if (what == "dog") dog = DogLike(data);
+ else if (what == "vow") vow = data;
+ else if (what == "calc") calc = AbacusLike(data);
else revert("Clipper/file-unrecognized-param");
emit File(what, data);
}
// --- Math ---
- uint256 constant BLN = 10 ** 9;
+ uint256 constant BLN = 10 ** 9;
uint256 constant WAD = 10 ** 18;
uint256 constant RAY = 10 ** 27;
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x <= y ? x : y;
}
+
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
+
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
+
function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, y) / WAD;
}
+
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, y) / RAY;
}
+
function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, RAY) / y;
}
@@ -211,7 +220,7 @@ contract Clipper {
// if mat has changed since the last poke, the resulting value will be
// incorrect.
function getFeedPrice() internal returns (uint256 feedPrice) {
- (PipLike pip, ) = spotter.ilks(ilk);
+ (PipLike pip,) = spotter.ilks(ilk);
(bytes32 val, bool has) = pip.peek();
require(has, "Clipper/invalid-price");
feedPrice = rdiv(mul(uint256(val), BLN), spotter.par());
@@ -227,17 +236,23 @@ contract Clipper {
// multiplicative factor to increase the starting price, and `par` is a
// reference per DAI.
function kick(
- uint256 tab, // Debt [rad]
- uint256 lot, // Collateral [wad]
- address usr, // Address that will receive any leftover collateral
- address kpr // Address that will receive incentives
- ) external auth lock isStopped(1) returns (uint256 id) {
+ uint256 tab, // Debt [rad]
+ uint256 lot, // Collateral [wad]
+ address usr, // Address that will receive any leftover collateral
+ address kpr // Address that will receive incentives
+ )
+ external
+ auth
+ lock
+ isStopped(1)
+ returns (uint256 id)
+ {
// Input validation
- require(tab > 0, "Clipper/zero-tab");
- require(lot > 0, "Clipper/zero-lot");
+ require(tab > 0, "Clipper/zero-tab");
+ require(lot > 0, "Clipper/zero-lot");
require(usr != address(0), "Clipper/zero-usr");
id = ++kicks;
- require(id > 0, "Clipper/overflow");
+ require(id > 0, "Clipper/overflow");
active.push(id);
@@ -254,7 +269,7 @@ contract Clipper {
sales[id].top = top;
// incentive to kick auction
- uint256 _tip = tip;
+ uint256 _tip = tip;
uint256 _chip = chip;
uint256 coin;
if (_tip > 0 || _chip > 0) {
@@ -268,12 +283,16 @@ contract Clipper {
// Reset an auction
// See `kick` above for an explanation of the computation of `top`.
function redo(
- uint256 id, // id of the auction to reset
- address kpr // Address that will receive incentives
- ) external lock isStopped(2) {
+ uint256 id, // id of the auction to reset
+ address kpr // Address that will receive incentives
+ )
+ external
+ lock
+ isStopped(2)
+ {
// Read auction data
address usr = sales[id].usr;
- uint96 tic = sales[id].tic;
+ uint96 tic = sales[id].tic;
uint256 top = sales[id].top;
require(usr != address(0), "Clipper/not-running-auction");
@@ -283,8 +302,8 @@ contract Clipper {
(bool done,) = status(tic, top);
require(done, "Clipper/cannot-reset");
- uint256 tab = sales[id].tab;
- uint256 lot = sales[id].lot;
+ uint256 tab = sales[id].tab;
+ uint256 lot = sales[id].lot;
sales[id].tic = uint96(block.timestamp);
uint256 feedPrice = getFeedPrice();
@@ -293,7 +312,7 @@ contract Clipper {
sales[id].top = top;
// incentive to redo auction
- uint256 _tip = tip;
+ uint256 _tip = tip;
uint256 _chip = chip;
uint256 coin;
if (_tip > 0 || _chip > 0) {
@@ -308,7 +327,7 @@ contract Clipper {
}
// Buy up to `amt` of collateral from the auction indexed by `id`.
- //
+ //
// Auctions will not collect more DAI than their assigned DAI target,`tab`;
// thus, if `amt` would cost more DAI than `tab` at the current price, the
// amount of collateral purchased will instead be just enough to collect `tab` DAI.
@@ -325,15 +344,18 @@ contract Clipper {
// If `tab <= chost`, partial purchases are no longer possible; that is, the remaining
// collateral can only be purchased entirely, or not at all.
function take(
- uint256 id, // Auction id
- uint256 amt, // Upper limit on amount of collateral to buy [wad]
- uint256 max, // Maximum acceptable price (DAI / collateral) [ray]
- address who, // Receiver of collateral and external call address
- bytes calldata data // Data to pass in external call; if length 0, no call is done
- ) external lock isStopped(3) {
-
+ uint256 id, // Auction id
+ uint256 amt, // Upper limit on amount of collateral to buy [wad]
+ uint256 max, // Maximum acceptable price (DAI / collateral) [ray]
+ address who, // Receiver of collateral and external call address
+ bytes calldata data // Data to pass in external call; if length 0, no call is done
+ )
+ external
+ lock
+ isStopped(3)
+ {
address usr = sales[id].usr;
- uint96 tic = sales[id].tic;
+ uint96 tic = sales[id].tic;
require(usr != address(0), "Clipper/not-running-auction");
@@ -355,7 +377,7 @@ contract Clipper {
{
// Purchase as much as possible, up to amt
- uint256 slice = min(lot, amt); // slice <= lot
+ uint256 slice = min(lot, amt); // slice <= lot
// DAI needed to buy a slice of this sale
owe = mul(slice, price);
@@ -363,24 +385,25 @@ contract Clipper {
// Don't collect more than tab of DAI
if (owe > tab) {
// Total debt will be paid
- owe = tab; // owe' <= owe
+ owe = tab; // owe' <= owe
// Adjust slice
- slice = owe / price; // slice' = owe' / price <= owe / price == slice <= lot
+ slice = owe / price; // slice' = owe' / price <= owe / price == slice <= lot
} else if (owe < tab && slice < lot) {
// If slice == lot => auction completed => dust doesn't matter
uint256 _chost = chost;
- if (tab - owe < _chost) { // safe as owe < tab
+ if (tab - owe < _chost) {
+ // safe as owe < tab
// If tab <= chost, buyers have to take the entire lot.
require(tab > _chost, "Clipper/no-partial-purchase");
// Adjust amount to pay
- owe = tab - _chost; // owe' <= owe
+ owe = tab - _chost; // owe' <= owe
// Adjust slice
- slice = owe / price; // slice' = owe' / price < owe / price == slice < lot
+ slice = owe / price; // slice' = owe' / price < owe / price == slice < lot
}
}
// Calculate remaining tab after operation
- tab = tab - owe; // safe since owe <= tab
+ tab = tab - owe; // safe since owe <= tab
// Calculate remaining lot after operation
lot = lot - slice;
@@ -416,10 +439,10 @@ contract Clipper {
}
function _remove(uint256 id) internal {
- uint256 _move = active[active.length - 1];
+ uint256 _move = active[active.length - 1];
if (id != _move) {
- uint256 _index = sales[id].pos;
- active[_index] = _move;
+ uint256 _index = sales[id].pos;
+ active[_index] = _move;
sales[_move].pos = _index;
}
active.pop();
@@ -440,7 +463,7 @@ contract Clipper {
function getStatus(uint256 id) external view returns (bool needsRedo, uint256 price, uint256 lot, uint256 tab) {
// Read auction data
address usr = sales[id].usr;
- uint96 tic = sales[id].tic;
+ uint96 tic = sales[id].tic;
bool done;
(done, price) = status(tic, sales[id].top);
@@ -453,7 +476,7 @@ contract Clipper {
// Internally returns boolean for if an auction needs a redo
function status(uint96 tic, uint256 top) internal view returns (bool done, uint256 price) {
price = calc.price(top, sub(block.timestamp, tic));
- done = (sub(block.timestamp, tic) > tail || rdiv(price, top) < cusp);
+ done = (sub(block.timestamp, tic) > tail || rdiv(price, top) < cusp);
}
// Public function to update the cached dust*chop value.
diff --git a/src/cure.sol b/src/cure.sol
index 8403808f..181a1bb7 100644
--- a/src/cure.sol
+++ b/src/cure.sol
@@ -24,14 +24,14 @@ interface SourceLike {
}
contract Cure {
- mapping (address => uint256) public wards;
+ mapping(address => uint256) public wards;
uint256 public live;
address[] public srcs;
uint256 public wait;
uint256 public when;
- mapping (address => uint256) public pos; // position in srcs + 1, 0 means a source does not exist
- mapping (address => uint256) public amt;
- mapping (address => uint256) public loaded;
+ mapping(address => uint256) public pos; // position in srcs + 1, 0 means a source does not exist
+ mapping(address => uint256) public amt;
+ mapping(address => uint256) public loaded;
uint256 public lCount;
uint256 public say;
@@ -44,7 +44,7 @@ contract Cure {
event Load(address indexed src);
event Cage();
- modifier auth {
+ modifier auth() {
require(wards[msg.sender] == 1, "Cure/not-authorized");
_;
}
@@ -73,7 +73,9 @@ contract Cure {
}
function tell() external view returns (uint256) {
- require(live == 0 && (lCount == srcs.length || block.timestamp >= when), "Cure/missing-load-and-time-not-passed");
+ require(
+ live == 0 && (lCount == srcs.length || block.timestamp >= when), "Cure/missing-load-and-time-not-passed"
+ );
return say;
}
diff --git a/src/dai.sol b/src/dai.sol
index efc1da28..5e6eb8d4 100644
--- a/src/dai.sol
+++ b/src/dai.sol
@@ -17,130 +17,227 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-pragma solidity ^0.6.12;
+pragma solidity ^0.8.0;
// FIXME: This contract was altered compared to the production version.
// It doesn't use LibNote anymore.
// New deployments of this contract will need to include custom events (TO DO).
-contract Dai {
- // --- Auth ---
- mapping (address => uint) public wards;
- function rely(address guy) external auth { wards[guy] = 1; }
- function deny(address guy) external auth { wards[guy] = 0; }
- modifier auth {
- require(wards[msg.sender] == 1, "Dai/not-authorized");
- _;
- }
+/**
+ * @title DAI_Contract
+ * @author MakerDAO
+ * @notice This contract was altered compared to the production version.
+ * It doesn't use LibNote anymore.
+ * New deployments of this contract will need to include custom events (TO DO).
+ * @dev This contract upgrades compile version making for Gas Optimization
+ */
- // --- ERC20 Data ---
- string public constant name = "Dai Stablecoin";
- string public constant symbol = "DAI";
- string public constant version = "1";
- uint8 public constant decimals = 18;
+contract Dai {
+ /*//////////////////////////////////////////////////////////////
+ ERRORS
+ //////////////////////////////////////////////////////////////*/
+ error Dai__InsufficientBalance();
+ error Dai__InsufficientAllowance();
+ error Dai__InvalidAddress();
+ error Dai__InvalidPermit();
+ error Dai__PermitExpired();
+ error Dai__InvalidNonce();
+ error Dai__DaiNotAuthorized();
+
+ /*//////////////////////////////////////////////////////////////
+ STATE VARIABLES
+ //////////////////////////////////////////////////////////////*/
+
+ string private constant name = "Dai Stablecoin";
+ string private constant symbol = "DAI";
+ string private constant version = "1";
+ uint8 private constant decimals = 18;
uint256 public totalSupply;
+ uint256 internal constant MAX_UINT = type(uint256).max;
- mapping (address => uint) public balanceOf;
- mapping (address => mapping (address => uint)) public allowance;
- mapping (address => uint) public nonces;
-
- event Approval(address indexed src, address indexed guy, uint wad);
- event Transfer(address indexed src, address indexed dst, uint wad);
-
- // --- Math ---
- function add(uint x, uint y) internal pure returns (uint z) {
- require((z = x + y) >= x);
- }
- function sub(uint x, uint y) internal pure returns (uint z) {
- require((z = x - y) <= x);
- }
+ /*//////////////////////////////////////////////////////////////
+ BYTES VARIABLES
+ //////////////////////////////////////////////////////////////*/
// --- EIP712 niceties ---
bytes32 public DOMAIN_SEPARATOR;
// bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;
+ bytes32 internal constant EIP712_DOMAIN_TYPEHASH =
+ keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
+
+ bytes32 internal constant NAME_HASH = keccak256(abi.encodePacked(name));
+
+ bytes32 internal constant VERSION_HASH = keccak256(abi.encodePacked(version));
+
+ /*//////////////////////////////////////////////////////////////
+ MAPPINGS
+ //////////////////////////////////////////////////////////////*/
+
+ mapping(address => uint256) public wards;
+ mapping(address => uint256) public balanceOf;
+ mapping(address => mapping(address => uint256)) public allowance;
+ mapping(address => uint256) public nonces;
+
+ /*//////////////////////////////////////////////////////////////
+ EVENTS
+ //////////////////////////////////////////////////////////////*/
- constructor(uint256 chainId_) public {
+ event Approval(address indexed src, address indexed guy, uint256 wad);
+ event Transfer(address indexed src, address indexed dst, uint256 wad);
+
+ /*//////////////////////////////////////////////////////////////
+ CONSTRUCTOR
+ //////////////////////////////////////////////////////////////*/
+
+ constructor(uint256 chainId_) {
wards[msg.sender] = 1;
- DOMAIN_SEPARATOR = keccak256(abi.encode(
- keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
- keccak256(bytes(name)),
- keccak256(bytes(version)),
- chainId_,
- address(this)
- ));
+ DOMAIN_SEPARATOR =
+ keccak256(abi.encode(EIP712_DOMAIN_TYPEHASH, NAME_HASH, VERSION_HASH, chainId_, address(this)));
+ }
+ /*//////////////////////////////////////////////////////////////
+ MODIFIER
+ //////////////////////////////////////////////////////////////*/
+
+ modifier auth() {
+ if (wards[msg.sender] != 1) {
+ revert Dai__DaiNotAuthorized();
+ }
+ _;
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ EXTERNAL FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+
+ function rely(address guy) external auth {
+ wards[guy] = 1;
+ }
+
+ function deny(address guy) external auth {
+ wards[guy] = 0;
}
// --- Token ---
- function transfer(address dst, uint wad) external returns (bool) {
+ function transfer(address dst, uint256 wad) external returns (bool) {
return transferFrom(msg.sender, dst, wad);
}
- function transferFrom(address src, address dst, uint wad)
- public returns (bool)
- {
- require(balanceOf[src] >= wad, "Dai/insufficient-balance");
- if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
- require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance");
- allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
+
+ function transferFrom(address src, address dst, uint256 wad) public returns (bool) {
+ uint256 srcBalance = balanceOf[src];
+
+ if (srcBalance < wad) {
+ revert Dai__InsufficientBalance();
}
- balanceOf[src] = sub(balanceOf[src], wad);
- balanceOf[dst] = add(balanceOf[dst], wad);
+
+ if (src != msg.sender) {
+ uint256 allowed = allowance[src][msg.sender];
+
+ if (allowed != MAX_UINT) {
+ if (allowed < wad) {
+ revert Dai__InsufficientAllowance();
+ }
+
+ unchecked {
+ allowance[src][msg.sender] = allowed - wad;
+ }
+ }
+ }
+
+ uint256 dstBalance = balanceOf[dst];
+
+ unchecked {
+ balanceOf[src] = srcBalance - wad;
+ balanceOf[dst] = dstBalance + wad;
+ }
+
emit Transfer(src, dst, wad);
+
return true;
}
- function mint(address usr, uint wad) external auth {
- balanceOf[usr] = add(balanceOf[usr], wad);
- totalSupply = add(totalSupply, wad);
+
+ function mint(address usr, uint256 wad) external auth {
+ balanceOf[usr] += wad;
+ totalSupply += wad;
+
emit Transfer(address(0), usr, wad);
}
- function burn(address usr, uint wad) external {
- require(balanceOf[usr] >= wad, "Dai/insufficient-balance");
- if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) {
- require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance");
- allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);
+
+ function burn(address usr, uint256 wad) external {
+ uint256 usrBalance = balanceOf[usr];
+
+ if (usrBalance < wad) revert Dai__InsufficientBalance();
+
+ if (usr != msg.sender) {
+ uint256 allowed = allowance[usr][msg.sender];
+
+ if (allowed != MAX_UINT) {
+ if (allowed < wad) revert Dai__InsufficientAllowance();
+
+ unchecked {
+ allowance[usr][msg.sender] = allowed - wad;
+ }
+ }
}
- balanceOf[usr] = sub(balanceOf[usr], wad);
- totalSupply = sub(totalSupply, wad);
+
+ unchecked {
+ balanceOf[usr] = usrBalance - wad;
+ totalSupply -= wad;
+ }
+
emit Transfer(usr, address(0), wad);
}
- function approve(address usr, uint wad) external returns (bool) {
+
+ function approve(address usr, uint256 wad) external returns (bool) {
allowance[msg.sender][usr] = wad;
emit Approval(msg.sender, usr, wad);
return true;
}
// --- Alias ---
- function push(address usr, uint wad) external {
+ function push(address usr, uint256 wad) external {
transferFrom(msg.sender, usr, wad);
}
- function pull(address usr, uint wad) external {
+
+ function pull(address usr, uint256 wad) external {
transferFrom(usr, msg.sender, wad);
}
- function move(address src, address dst, uint wad) external {
+
+ function move(address src, address dst, uint256 wad) external {
transferFrom(src, dst, wad);
}
// --- Approve by signature ---
- function permit(address holder, address spender, uint256 nonce, uint256 expiry,
- bool allowed, uint8 v, bytes32 r, bytes32 s) external
- {
- bytes32 digest =
- keccak256(abi.encodePacked(
+ function permit(
+ address holder,
+ address spender,
+ uint256 nonce,
+ uint256 expiry,
+ bool allowed,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) external {
+ bytes32 digest = keccak256(
+ abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
- keccak256(abi.encode(PERMIT_TYPEHASH,
- holder,
- spender,
- nonce,
- expiry,
- allowed))
- ));
-
- require(holder != address(0), "Dai/invalid-address-0");
- require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit");
- require(expiry == 0 || now <= expiry, "Dai/permit-expired");
- require(nonce == nonces[holder]++, "Dai/invalid-nonce");
- uint wad = allowed ? uint(-1) : 0;
+ keccak256(abi.encode(PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed))
+ )
+ );
+ if (holder == address(0)) {
+ revert Dai__InvalidAddress();
+ }
+ if (holder != ecrecover(digest, v, r, s)) {
+ revert Dai__InvalidPermit();
+ }
+ if (expiry != 0 && block.timestamp > expiry) {
+ revert Dai__PermitExpired();
+ }
+ if (nonce != nonces[holder]++) {
+ revert Dai__InvalidNonce();
+ }
+ uint256 wad = allowed ? MAX_UINT : 0;
allowance[holder][spender] = wad;
emit Approval(holder, spender, wad);
}
diff --git a/src/dog.sol b/src/dog.sol
index d941d80f..9f6e7507 100644
--- a/src/dog.sol
+++ b/src/dog.sol
@@ -21,27 +21,28 @@ pragma solidity ^0.6.12;
interface ClipperLike {
function ilk() external view returns (bytes32);
- function kick(
- uint256 tab,
- uint256 lot,
- address usr,
- address kpr
- ) external returns (uint256);
+ function kick(uint256 tab, uint256 lot, address usr, address kpr) external returns (uint256);
}
interface VatLike {
- function ilks(bytes32) external view returns (
- uint256 Art, // [wad]
- uint256 rate, // [ray]
- uint256 spot, // [ray]
- uint256 line, // [rad]
- uint256 dust // [rad]
- );
- function urns(bytes32,address) external view returns (
- uint256 ink, // [wad]
- uint256 art // [wad]
- );
- function grab(bytes32,address,address,address,int256,int256) external;
+ function ilks(bytes32)
+ external
+ view
+ returns (
+ uint256 Art, // [wad]
+ uint256 rate, // [ray]
+ uint256 spot, // [ray]
+ uint256 line, // [rad]
+ uint256 dust // [rad]
+ );
+ function urns(bytes32, address)
+ external
+ view
+ returns (
+ uint256 ink, // [wad]
+ uint256 art // [wad]
+ );
+ function grab(bytes32, address, address, address, int256, int256) external;
function hope(address) external;
function nope(address) external;
}
@@ -52,30 +53,38 @@ interface VowLike {
contract Dog {
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Dog/not-authorized");
_;
}
// --- Data ---
struct Ilk {
- address clip; // Liquidator
- uint256 chop; // Liquidation Penalty [wad]
- uint256 hole; // Max DAI needed to cover debt+fees of active auctions per ilk [rad]
- uint256 dirt; // Amt DAI needed to cover debt+fees of active auctions per ilk [rad]
+ address clip; // Liquidator
+ uint256 chop; // Liquidation Penalty [wad]
+ uint256 hole; // Max DAI needed to cover debt+fees of active auctions per ilk [rad]
+ uint256 dirt; // Amt DAI needed to cover debt+fees of active auctions per ilk [rad]
}
- VatLike immutable public vat; // CDP Engine
+ VatLike public immutable vat; // CDP Engine
- mapping (bytes32 => Ilk) public ilks;
+ mapping(bytes32 => Ilk) public ilks;
- VowLike public vow; // Debt Engine
- uint256 public live; // Active Flag
- uint256 public Hole; // Max DAI needed to cover debt+fees of active auctions [rad]
- uint256 public Dirt; // Amt DAI needed to cover debt+fees of active auctions [rad]
+ VowLike public vow; // Debt Engine
+ uint256 public live; // Active Flag
+ uint256 public Hole; // Max DAI needed to cover debt+fees of active auctions [rad]
+ uint256 public Dirt; // Amt DAI needed to cover debt+fees of active auctions [rad]
// --- Events ---
event Rely(address indexed usr);
@@ -87,13 +96,13 @@ contract Dog {
event File(bytes32 indexed ilk, bytes32 indexed what, address clip);
event Bark(
- bytes32 indexed ilk,
- address indexed urn,
- uint256 ink,
- uint256 art,
- uint256 due,
- address clip,
- uint256 indexed id
+ bytes32 indexed ilk,
+ address indexed urn,
+ uint256 ink,
+ uint256 art,
+ uint256 due,
+ address clip,
+ uint256 indexed id
);
event Digs(bytes32 indexed ilk, uint256 rad);
event Cage();
@@ -112,12 +121,15 @@ contract Dog {
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x <= y ? x : y;
}
+
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
+
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -128,24 +140,32 @@ contract Dog {
else revert("Dog/file-unrecognized-param");
emit File(what, data);
}
+
function file(bytes32 what, uint256 data) external auth {
if (what == "Hole") Hole = data;
else revert("Dog/file-unrecognized-param");
emit File(what, data);
}
+
function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
if (what == "chop") {
require(data >= WAD, "Dog/file-chop-lt-WAD");
ilks[ilk].chop = data;
- } else if (what == "hole") ilks[ilk].hole = data;
- else revert("Dog/file-unrecognized-param");
+ } else if (what == "hole") {
+ ilks[ilk].hole = data;
+ } else {
+ revert("Dog/file-unrecognized-param");
+ }
emit File(ilk, what, data);
}
+
function file(bytes32 ilk, bytes32 what, address clip) external auth {
if (what == "clip") {
require(ilk == ClipperLike(clip).ilk(), "Dog/file-ilk-neq-clip.ilk");
ilks[ilk].clip = clip;
- } else revert("Dog/file-unrecognized-param");
+ } else {
+ revert("Dog/file-unrecognized-param");
+ }
emit File(ilk, what, clip);
}
@@ -177,7 +197,7 @@ contract Dog {
uint256 dust;
{
uint256 spot;
- (,rate, spot,, dust) = vat.ilks(ilk);
+ (, rate, spot,, dust) = vat.ilks(ilk);
require(spot > 0 && mul(ink, spot) < mul(art, rate), "Dog/not-unsafe");
// Get the minimum value between:
@@ -192,7 +212,6 @@ contract Dog {
// Partial liquidation edge case logic
if (art > dart) {
if (mul(art - dart, rate) < dust) {
-
// If the leftover Vault would be dusty, just liquidate it entirely.
// This will result in at least one of dirt_i > hole_i or Dirt > Hole becoming true.
// The amount of excess will be bounded above by ceiling(dust_i * chop_i / WAD).
@@ -200,7 +219,6 @@ contract Dog {
// the extra amount of target DAI over the limits intended is not of economic concern.
dart = art;
} else {
-
// In a partial liquidation, the resulting auction should also be non-dusty.
require(mul(dart, rate) >= dust, "Dog/dusty-auction-from-partial-liquidation");
}
@@ -210,27 +228,20 @@ contract Dog {
uint256 dink = mul(ink, dart) / art;
require(dink > 0, "Dog/null-auction");
- require(dart <= 2**255 && dink <= 2**255, "Dog/overflow");
+ require(dart <= 2 ** 255 && dink <= 2 ** 255, "Dog/overflow");
- vat.grab(
- ilk, urn, milk.clip, address(vow), -int256(dink), -int256(dart)
- );
+ vat.grab(ilk, urn, milk.clip, address(vow), -int256(dink), -int256(dart));
uint256 due = mul(dart, rate);
vow.fess(due);
- { // Avoid stack too deep
+ { // Avoid stack too deep
// This calcuation will overflow if dart*rate exceeds ~10^14
uint256 tab = mul(due, milk.chop) / WAD;
Dirt = add(Dirt, tab);
ilks[ilk].dirt = add(milk.dirt, tab);
- id = ClipperLike(milk.clip).kick({
- tab: tab,
- lot: dink,
- usr: urn,
- kpr: kpr
- });
+ id = ClipperLike(milk.clip).kick({tab: tab, lot: dink, usr: urn, kpr: kpr});
}
emit Bark(ilk, urn, dink, dart, due, milk.clip, id);
diff --git a/src/end.sol b/src/end.sol
index 14e17b19..ade9d253 100644
--- a/src/end.sol
+++ b/src/end.sol
@@ -23,17 +23,21 @@ pragma solidity ^0.6.12;
interface VatLike {
function dai(address) external view returns (uint256);
- function ilks(bytes32 ilk) external returns (
- uint256 Art, // [wad]
- uint256 rate, // [ray]
- uint256 spot, // [ray]
- uint256 line, // [rad]
- uint256 dust // [rad]
- );
- function urns(bytes32 ilk, address urn) external returns (
- uint256 ink, // [wad]
- uint256 art // [wad]
- );
+ function ilks(bytes32 ilk)
+ external
+ returns (
+ uint256 Art, // [wad]
+ uint256 rate, // [ray]
+ uint256 spot, // [ray]
+ uint256 line, // [rad]
+ uint256 dust // [rad]
+ );
+ function urns(bytes32 ilk, address urn)
+ external
+ returns (
+ uint256 ink, // [wad]
+ uint256 art // [wad]
+ );
function debt() external returns (uint256);
function move(address src, address dst, uint256 rad) external;
function hope(address) external;
@@ -44,21 +48,18 @@ interface VatLike {
}
interface CatLike {
- function ilks(bytes32) external returns (
- address flip,
- uint256 chop, // [ray]
- uint256 lump // [rad]
- );
+ function ilks(bytes32)
+ external
+ returns (
+ address flip,
+ uint256 chop, // [ray]
+ uint256 lump // [rad]
+ );
function cage() external;
}
interface DogLike {
- function ilks(bytes32) external returns (
- address clip,
- uint256 chop,
- uint256 hole,
- uint256 dirt
- );
+ function ilks(bytes32) external returns (address clip, uint256 chop, uint256 hole, uint256 dirt);
function cage() external;
}
@@ -71,28 +72,27 @@ interface VowLike {
}
interface FlipLike {
- function bids(uint256 id) external view returns (
- uint256 bid, // [rad]
- uint256 lot, // [wad]
- address guy,
- uint48 tic, // [unix epoch time]
- uint48 end, // [unix epoch time]
- address usr,
- address gal,
- uint256 tab // [rad]
- );
+ function bids(uint256 id)
+ external
+ view
+ returns (
+ uint256 bid, // [rad]
+ uint256 lot, // [wad]
+ address guy,
+ uint48 tic, // [unix epoch time]
+ uint48 end, // [unix epoch time]
+ address usr,
+ address gal,
+ uint256 tab // [rad]
+ );
function yank(uint256 id) external;
}
interface ClipLike {
- function sales(uint256 id) external view returns (
- uint256 pos,
- uint256 tab,
- uint256 lot,
- address usr,
- uint96 tic,
- uint256 top
- );
+ function sales(uint256 id)
+ external
+ view
+ returns (uint256 pos, uint256 tab, uint256 lot, address usr, uint96 tic, uint256 top);
function yank(uint256 id) external;
}
@@ -102,10 +102,13 @@ interface PipLike {
interface SpotLike {
function par() external view returns (uint256);
- function ilks(bytes32) external view returns (
- PipLike pip,
- uint256 mat // [ray]
- );
+ function ilks(bytes32)
+ external
+ view
+ returns (
+ PipLike pip,
+ uint256 mat // [ray]
+ );
function cage() external;
}
@@ -231,35 +234,43 @@ interface CureLike {
contract End {
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
- function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ emit Rely(usr);
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ emit Deny(usr);
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "End/not-authorized");
_;
}
// --- Data ---
- VatLike public vat; // CDP Engine
- CatLike public cat;
- DogLike public dog;
- VowLike public vow; // Debt Engine
- PotLike public pot;
+ VatLike public vat; // CDP Engine
+ CatLike public cat;
+ DogLike public dog;
+ VowLike public vow; // Debt Engine
+ PotLike public pot;
SpotLike public spot;
CureLike public cure;
- uint256 public live; // Active Flag
- uint256 public when; // Time of cage [unix epoch time]
- uint256 public wait; // Processing Cooldown Length [seconds]
- uint256 public debt; // Total outstanding dai following processing [rad]
+ uint256 public live; // Active Flag
+ uint256 public when; // Time of cage [unix epoch time]
+ uint256 public wait; // Processing Cooldown Length [seconds]
+ uint256 public debt; // Total outstanding dai following processing [rad]
- mapping (bytes32 => uint256) public tag; // Cage price [ray]
- mapping (bytes32 => uint256) public gap; // Collateral shortfall [wad]
- mapping (bytes32 => uint256) public Art; // Total debt per ilk [wad]
- mapping (bytes32 => uint256) public fix; // Final cash price [ray]
+ mapping(bytes32 => uint256) public tag; // Cage price [ray]
+ mapping(bytes32 => uint256) public gap; // Collateral shortfall [wad]
+ mapping(bytes32 => uint256) public Art; // Total debt per ilk [wad]
+ mapping(bytes32 => uint256) public fix; // Final cash price [ray]
- mapping (address => uint256) public bag; // [wad]
- mapping (bytes32 => mapping (address => uint256)) public out; // [wad]
+ mapping(address => uint256) public bag; // [wad]
+ mapping(bytes32 => mapping(address => uint256)) public out; // [wad]
// --- Events ---
event Rely(address indexed usr);
@@ -289,22 +300,28 @@ contract End {
// --- Math ---
uint256 constant WAD = 10 ** 18;
uint256 constant RAY = 10 ** 27;
+
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x + y;
require(z >= x);
}
+
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
+
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
return x <= y ? x : y;
}
+
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, y) / RAY;
}
+
function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, WAD) / y;
}
@@ -312,16 +329,17 @@ contract End {
// --- Administration ---
function file(bytes32 what, address data) external auth {
require(live == 1, "End/not-live");
- if (what == "vat") vat = VatLike(data);
- else if (what == "cat") cat = CatLike(data);
- else if (what == "dog") dog = DogLike(data);
- else if (what == "vow") vow = VowLike(data);
- else if (what == "pot") pot = PotLike(data);
+ if (what == "vat") vat = VatLike(data);
+ else if (what == "cat") cat = CatLike(data);
+ else if (what == "dog") dog = DogLike(data);
+ else if (what == "vow") vow = VowLike(data);
+ else if (what == "pot") pot = PotLike(data);
else if (what == "spot") spot = SpotLike(data);
else if (what == "cure") cure = CureLike(data);
else revert("End/file-unrecognized-param");
emit File(what, data);
}
+
function file(bytes32 what, uint256 data) external auth {
require(live == 1, "End/not-live");
if (what == "wait") wait = data;
@@ -362,7 +380,7 @@ contract End {
(, uint256 rate,,,) = vat.ilks(ilk);
(, uint256 tab, uint256 lot, address usr,,) = clip.sales(id);
- vat.suck(address(vow), address(vow), tab);
+ vat.suck(address(vow), address(vow), tab);
clip.yank(id);
uint256 art = tab / rate;
@@ -380,7 +398,7 @@ contract End {
(, uint256 rate,,,) = vat.ilks(ilk);
(uint256 bid, uint256 lot,,,, address usr,, uint256 tab) = flip.bids(id);
- vat.suck(address(vow), address(vow), tab);
+ vat.suck(address(vow), address(vow), tab);
vat.suck(address(vow), address(this), bid);
vat.hope(address(flip));
flip.yank(id);
@@ -401,7 +419,7 @@ contract End {
uint256 wad = min(ink, owe);
gap[ilk] = add(gap[ilk], sub(owe, wad));
- require(wad <= 2**255 && art <= 2**255, "End/overflow");
+ require(wad <= 2 ** 255 && art <= 2 ** 255, "End/overflow");
vat.grab(ilk, urn, address(this), address(vow), -int256(wad), -int256(art));
emit Skim(ilk, urn, wad, art);
}
@@ -410,7 +428,7 @@ contract End {
require(live == 0, "End/still-live");
(uint256 ink, uint256 art) = vat.urns(ilk, msg.sender);
require(art == 0, "End/art-not-zero");
- require(ink <= 2**255, "End/overflow");
+ require(ink <= 2 ** 255, "End/overflow");
vat.grab(ilk, msg.sender, msg.sender, address(vow), -int256(ink), 0);
emit Free(ilk, msg.sender, ink);
}
@@ -423,6 +441,7 @@ contract End {
debt = sub(vat.debt(), cure.tell());
emit Thaw();
}
+
function flow(bytes32 ilk) external {
require(debt != 0, "End/debt-zero");
require(fix[ilk] == 0, "End/fix-ilk-already-defined");
@@ -439,6 +458,7 @@ contract End {
bag[msg.sender] = add(bag[msg.sender], wad);
emit Pack(msg.sender, wad);
}
+
function cash(bytes32 ilk, uint256 wad) external {
require(fix[ilk] != 0, "End/fix-ilk-not-defined");
vat.flux(ilk, address(this), msg.sender, rmul(wad, fix[ilk]));
diff --git a/src/flap.sol b/src/flap.sol
index 8a0125bb..731718a5 100644
--- a/src/flap.sol
+++ b/src/flap.sol
@@ -25,11 +25,12 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface VatLike {
- function move(address,address,uint) external;
+ function move(address, address, uint256) external;
}
+
interface GemLike {
- function move(address,address,uint) external;
- function burn(address,uint) external;
+ function move(address, address, uint256) external;
+ function burn(address, uint256) external;
}
/*
@@ -44,43 +45,45 @@ interface GemLike {
contract Flapper {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address usr) external auth { wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Flapper/not-authorized");
_;
}
// --- Data ---
struct Bid {
- uint256 bid; // gems paid [wad]
- uint256 lot; // dai in return for bid [rad]
- address guy; // high bidder
- uint48 tic; // bid expiry time [unix epoch time]
- uint48 end; // auction expiry time [unix epoch time]
+ uint256 bid; // gems paid [wad]
+ uint256 lot; // dai in return for bid [rad]
+ address guy; // high bidder
+ uint48 tic; // bid expiry time [unix epoch time]
+ uint48 end; // auction expiry time [unix epoch time]
}
- mapping (uint => Bid) public bids;
+ mapping(uint256 => Bid) public bids;
- VatLike public vat; // CDP Engine
- GemLike public gem;
+ VatLike public vat; // CDP Engine
+ GemLike public gem;
- uint256 constant ONE = 1.00E18;
- uint256 public beg = 1.05E18; // 5% minimum bid increase
- uint48 public ttl = 3 hours; // 3 hours bid duration [seconds]
- uint48 public tau = 2 days; // 2 days total auction length [seconds]
- uint256 public kicks = 0;
- uint256 public live; // Active Flag
- uint256 public lid; // max dai to be in auction at one time [rad]
- uint256 public fill; // current dai in auction [rad]
+ uint256 constant ONE = 1.0e18;
+ uint256 public beg = 1.05e18; // 5% minimum bid increase
+ uint48 public ttl = 3 hours; // 3 hours bid duration [seconds]
+ uint48 public tau = 2 days; // 2 days total auction length [seconds]
+ uint256 public kicks = 0;
+ uint256 public live; // Active Flag
+ uint256 public lid; // max dai to be in auction at one time [rad]
+ uint256 public fill; // current dai in auction [rad]
// --- Events ---
- event Kick(
- uint256 id,
- uint256 lot,
- uint256 bid
- );
+ event Kick(uint256 id, uint256 lot, uint256 bid);
// --- Init ---
constructor(address vat_, address gem_) public {
@@ -94,18 +97,21 @@ contract Flapper {
function add(uint48 x, uint48 y) internal pure returns (uint48 z) {
require((z = x + y) >= x);
}
- function add256(uint x, uint y) internal pure returns (uint z) {
+
+ function add256(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
- function sub(uint x, uint y) internal pure returns (uint z) {
+
+ function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
- function mul(uint x, uint y) internal pure returns (uint z) {
+
+ function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
// --- Admin ---
- function file(bytes32 what, uint data) external auth {
+ function file(bytes32 what, uint256 data) external auth {
if (what == "beg") beg = data;
else if (what == "ttl") ttl = uint48(data);
else if (what == "tau") tau = uint48(data);
@@ -114,35 +120,37 @@ contract Flapper {
}
// --- Auction ---
- function kick(uint lot, uint bid) external auth returns (uint id) {
+ function kick(uint256 lot, uint256 bid) external auth returns (uint256 id) {
require(live == 1, "Flapper/not-live");
- require(kicks < uint(-1), "Flapper/overflow");
+ require(kicks < uint256(-1), "Flapper/overflow");
fill = add256(fill, lot);
require(fill <= lid, "Flapper/over-lid");
id = ++kicks;
bids[id].bid = bid;
bids[id].lot = lot;
- bids[id].guy = msg.sender; // configurable??
+ bids[id].guy = msg.sender; // configurable??
bids[id].end = add(uint48(now), tau);
vat.move(msg.sender, address(this), lot);
emit Kick(id, lot, bid);
}
- function tick(uint id) external {
+
+ function tick(uint256 id) external {
require(bids[id].end < now, "Flapper/not-finished");
require(bids[id].tic == 0, "Flapper/bid-already-placed");
bids[id].end = add(uint48(now), tau);
}
- function tend(uint id, uint lot, uint bid) external {
+
+ function tend(uint256 id, uint256 lot, uint256 bid) external {
require(live == 1, "Flapper/not-live");
require(bids[id].guy != address(0), "Flapper/guy-not-set");
require(bids[id].tic > now || bids[id].tic == 0, "Flapper/already-finished-tic");
require(bids[id].end > now, "Flapper/already-finished-end");
require(lot == bids[id].lot, "Flapper/lot-not-matching");
- require(bid > bids[id].bid, "Flapper/bid-not-higher");
+ require(bid > bids[id].bid, "Flapper/bid-not-higher");
require(mul(bid, ONE) >= mul(beg, bids[id].bid), "Flapper/insufficient-increase");
if (msg.sender != bids[id].guy) {
@@ -154,7 +162,8 @@ contract Flapper {
bids[id].bid = bid;
bids[id].tic = add(uint48(now), ttl);
}
- function deal(uint id) external {
+
+ function deal(uint256 id) external {
require(live == 1, "Flapper/not-live");
require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flapper/not-finished");
uint256 lot = bids[id].lot;
@@ -164,11 +173,12 @@ contract Flapper {
fill = sub(fill, lot);
}
- function cage(uint rad) external auth {
- live = 0;
- vat.move(address(this), msg.sender, rad);
+ function cage(uint256 rad) external auth {
+ live = 0;
+ vat.move(address(this), msg.sender, rad);
}
- function yank(uint id) external {
+
+ function yank(uint256 id) external {
require(live == 0, "Flapper/still-live");
require(bids[id].guy != address(0), "Flapper/guy-not-set");
gem.move(address(this), bids[id].guy, bids[id].bid);
diff --git a/src/flip.sol b/src/flip.sol
index 5b40dcab..8e5b091d 100644
--- a/src/flip.sol
+++ b/src/flip.sol
@@ -24,8 +24,8 @@ pragma solidity >=0.5.12;
// New deployments of this contract will need to include custom events (TO DO).
interface VatLike {
- function move(address,address,uint256) external;
- function flux(bytes32,address,address,uint256) external;
+ function move(address, address, uint256) external;
+ function flux(bytes32, address, address, uint256) external;
}
interface CatLike {
@@ -48,47 +48,46 @@ interface CatLike {
contract Flipper {
// --- Auth ---
- mapping (address => uint256) public wards;
- function rely(address usr) external auth { wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Flipper/not-authorized");
_;
}
// --- Data ---
struct Bid {
- uint256 bid; // dai paid [rad]
- uint256 lot; // gems in return for bid [wad]
- address guy; // high bidder
- uint48 tic; // bid expiry time [unix epoch time]
- uint48 end; // auction expiry time [unix epoch time]
+ uint256 bid; // dai paid [rad]
+ uint256 lot; // gems in return for bid [wad]
+ address guy; // high bidder
+ uint48 tic; // bid expiry time [unix epoch time]
+ uint48 end; // auction expiry time [unix epoch time]
address usr;
address gal;
- uint256 tab; // total dai wanted [rad]
+ uint256 tab; // total dai wanted [rad]
}
- mapping (uint256 => Bid) public bids;
+ mapping(uint256 => Bid) public bids;
- VatLike public vat; // CDP Engine
- bytes32 public ilk; // collateral type
+ VatLike public vat; // CDP Engine
+ bytes32 public ilk; // collateral type
- uint256 constant ONE = 1.00E18;
- uint256 public beg = 1.05E18; // 5% minimum bid increase
- uint48 public ttl = 3 hours; // 3 hours bid duration [seconds]
- uint48 public tau = 2 days; // 2 days total auction length [seconds]
+ uint256 constant ONE = 1.0e18;
+ uint256 public beg = 1.05e18; // 5% minimum bid increase
+ uint48 public ttl = 3 hours; // 3 hours bid duration [seconds]
+ uint48 public tau = 2 days; // 2 days total auction length [seconds]
uint256 public kicks = 0;
- CatLike public cat; // cat liquidation module
+ CatLike public cat; // cat liquidation module
// --- Events ---
- event Kick(
- uint256 id,
- uint256 lot,
- uint256 bid,
- uint256 tab,
- address indexed usr,
- address indexed gal
- );
+ event Kick(uint256 id, uint256 lot, uint256 bid, uint256 tab, address indexed usr, address indexed gal);
// --- Init ---
constructor(address vat_, address cat_, bytes32 ilk_) public {
@@ -102,6 +101,7 @@ contract Flipper {
function add(uint48 x, uint48 y) internal pure returns (uint48 z) {
require((z = x + y) >= x);
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -113,22 +113,21 @@ contract Flipper {
else if (what == "tau") tau = uint48(data);
else revert("Flipper/file-unrecognized-param");
}
+
function file(bytes32 what, address data) external auth {
if (what == "cat") cat = CatLike(data);
else revert("Flipper/file-unrecognized-param");
}
// --- Auction ---
- function kick(address usr, address gal, uint256 tab, uint256 lot, uint256 bid)
- public auth returns (uint256 id)
- {
- require(kicks < uint256(-1), "Flipper/overflow");
+ function kick(address usr, address gal, uint256 tab, uint256 lot, uint256 bid) public auth returns (uint256 id) {
+ require(kicks < type(uint256).max, "Flipper/overflow");
id = ++kicks;
bids[id].bid = bid;
bids[id].lot = lot;
- bids[id].guy = msg.sender; // configurable??
- bids[id].end = add(uint48(now), tau);
+ bids[id].guy = msg.sender; // configurable??
+ bids[id].end = add(uint48(block.timestamp), tau);
bids[id].usr = usr;
bids[id].gal = gal;
bids[id].tab = tab;
@@ -137,19 +136,21 @@ contract Flipper {
emit Kick(id, lot, bid, tab, usr, gal);
}
+
function tick(uint256 id) external {
- require(bids[id].end < now, "Flipper/not-finished");
+ require(bids[id].end < block.timestamp, "Flipper/not-finished");
require(bids[id].tic == 0, "Flipper/bid-already-placed");
- bids[id].end = add(uint48(now), tau);
+ bids[id].end = add(uint48(block.timestamp), tau);
}
+
function tend(uint256 id, uint256 lot, uint256 bid) external {
require(bids[id].guy != address(0), "Flipper/guy-not-set");
- require(bids[id].tic > now || bids[id].tic == 0, "Flipper/already-finished-tic");
- require(bids[id].end > now, "Flipper/already-finished-end");
+ require(bids[id].tic > block.timestamp || bids[id].tic == 0, "Flipper/already-finished-tic");
+ require(bids[id].end > block.timestamp, "Flipper/already-finished-end");
require(lot == bids[id].lot, "Flipper/lot-not-matching");
require(bid <= bids[id].tab, "Flipper/higher-than-tab");
- require(bid > bids[id].bid, "Flipper/bid-not-higher");
+ require(bid > bids[id].bid, "Flipper/bid-not-higher");
require(mul(bid, ONE) >= mul(beg, bids[id].bid) || bid == bids[id].tab, "Flipper/insufficient-increase");
if (msg.sender != bids[id].guy) {
@@ -159,12 +160,13 @@ contract Flipper {
vat.move(msg.sender, bids[id].gal, bid - bids[id].bid);
bids[id].bid = bid;
- bids[id].tic = add(uint48(now), ttl);
+ bids[id].tic = add(uint48(block.timestamp), ttl);
}
+
function dent(uint256 id, uint256 lot, uint256 bid) external {
require(bids[id].guy != address(0), "Flipper/guy-not-set");
- require(bids[id].tic > now || bids[id].tic == 0, "Flipper/already-finished-tic");
- require(bids[id].end > now, "Flipper/already-finished-end");
+ require(bids[id].tic > block.timestamp || bids[id].tic == 0, "Flipper/already-finished-tic");
+ require(bids[id].end > block.timestamp, "Flipper/already-finished-end");
require(bid == bids[id].bid, "Flipper/not-matching-bid");
require(bid == bids[id].tab, "Flipper/tend-not-finished");
@@ -178,10 +180,14 @@ contract Flipper {
vat.flux(ilk, address(this), bids[id].usr, bids[id].lot - lot);
bids[id].lot = lot;
- bids[id].tic = add(uint48(now), ttl);
+ bids[id].tic = add(uint48(block.timestamp), ttl);
}
+
function deal(uint256 id) external {
- require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flipper/not-finished");
+ require(
+ bids[id].tic != 0 && (bids[id].tic < block.timestamp || bids[id].end < block.timestamp),
+ "Flipper/not-finished"
+ );
cat.claw(bids[id].tab);
vat.flux(ilk, address(this), bids[id].guy, bids[id].lot);
delete bids[id];
diff --git a/src/flop.sol b/src/flop.sol
index 7752cb63..ca34ce78 100644
--- a/src/flop.sol
+++ b/src/flop.sol
@@ -24,15 +24,17 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface VatLike {
- function move(address,address,uint) external;
- function suck(address,address,uint) external;
+ function move(address, address, uint256) external;
+ function suck(address, address, uint256) external;
}
+
interface GemLike {
- function mint(address,uint) external;
+ function mint(address, uint256) external;
}
+
interface VowLike {
- function Ash() external returns (uint);
- function kiss(uint) external;
+ function Ash() external returns (uint256);
+ function kiss(uint256) external;
}
/*
@@ -48,44 +50,45 @@ interface VowLike {
contract Flopper {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address usr) external auth { wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Flopper/not-authorized");
_;
}
// --- Data ---
struct Bid {
- uint256 bid; // dai paid [rad]
- uint256 lot; // gems in return for bid [wad]
- address guy; // high bidder
- uint48 tic; // bid expiry time [unix epoch time]
- uint48 end; // auction expiry time [unix epoch time]
+ uint256 bid; // dai paid [rad]
+ uint256 lot; // gems in return for bid [wad]
+ address guy; // high bidder
+ uint48 tic; // bid expiry time [unix epoch time]
+ uint48 end; // auction expiry time [unix epoch time]
}
- mapping (uint => Bid) public bids;
+ mapping(uint256 => Bid) public bids;
- VatLike public vat; // CDP Engine
- GemLike public gem;
+ VatLike public vat; // CDP Engine
+ GemLike public gem;
- uint256 constant ONE = 1.00E18;
- uint256 public beg = 1.05E18; // 5% minimum bid increase
- uint256 public pad = 1.50E18; // 50% lot increase for tick
- uint48 public ttl = 3 hours; // 3 hours bid lifetime [seconds]
- uint48 public tau = 2 days; // 2 days total auction length [seconds]
- uint256 public kicks = 0;
- uint256 public live; // Active Flag
- address public vow; // not used until shutdown
+ uint256 constant ONE = 1.0e18;
+ uint256 public beg = 1.05e18; // 5% minimum bid increase
+ uint256 public pad = 1.5e18; // 50% lot increase for tick
+ uint48 public ttl = 3 hours; // 3 hours bid lifetime [seconds]
+ uint48 public tau = 2 days; // 2 days total auction length [seconds]
+ uint256 public kicks = 0;
+ uint256 public live; // Active Flag
+ address public vow; // not used until shutdown
// --- Events ---
- event Kick(
- uint256 id,
- uint256 lot,
- uint256 bid,
- address indexed gal
- );
+ event Kick(uint256 id, uint256 lot, uint256 bid, address indexed gal);
// --- Init ---
constructor(address vat_, address gem_) public {
@@ -99,15 +102,18 @@ contract Flopper {
function add(uint48 x, uint48 y) internal pure returns (uint48 z) {
require((z = x + y) >= x);
}
- function mul(uint x, uint y) internal pure returns (uint z) {
+
+ function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
- function min(uint x, uint y) internal pure returns (uint z) {
- if (x > y) { z = y; } else { z = x; }
+
+ function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
+ if (x > y) z = y;
+ else z = x;
}
// --- Admin ---
- function file(bytes32 what, uint data) external auth {
+ function file(bytes32 what, uint256 data) external auth {
if (what == "beg") beg = data;
else if (what == "pad") pad = data;
else if (what == "ttl") ttl = uint48(data);
@@ -116,9 +122,9 @@ contract Flopper {
}
// --- Auction ---
- function kick(address gal, uint lot, uint bid) external auth returns (uint id) {
+ function kick(address gal, uint256 lot, uint256 bid) external auth returns (uint256 id) {
require(live == 1, "Flopper/not-live");
- require(kicks < uint(-1), "Flopper/overflow");
+ require(kicks < uint256(-1), "Flopper/overflow");
id = ++kicks;
bids[id].bid = bid;
@@ -128,20 +134,22 @@ contract Flopper {
emit Kick(id, lot, bid, gal);
}
- function tick(uint id) external {
+
+ function tick(uint256 id) external {
require(bids[id].end < now, "Flopper/not-finished");
require(bids[id].tic == 0, "Flopper/bid-already-placed");
bids[id].lot = mul(pad, bids[id].lot) / ONE;
bids[id].end = add(uint48(now), tau);
}
- function dent(uint id, uint lot, uint bid) external {
+
+ function dent(uint256 id, uint256 lot, uint256 bid) external {
require(live == 1, "Flopper/not-live");
require(bids[id].guy != address(0), "Flopper/guy-not-set");
require(bids[id].tic > now || bids[id].tic == 0, "Flopper/already-finished-tic");
require(bids[id].end > now, "Flopper/already-finished-end");
require(bid == bids[id].bid, "Flopper/not-matching-bid");
- require(lot < bids[id].lot, "Flopper/lot-not-lower");
+ require(lot < bids[id].lot, "Flopper/lot-not-lower");
require(mul(beg, lot) <= mul(bids[id].lot, ONE), "Flopper/insufficient-decrease");
if (msg.sender != bids[id].guy) {
@@ -149,7 +157,7 @@ contract Flopper {
// on first dent, clear as much Ash as possible
if (bids[id].tic == 0) {
- uint Ash = VowLike(bids[id].guy).Ash();
+ uint256 Ash = VowLike(bids[id].guy).Ash();
VowLike(bids[id].guy).kiss(min(bid, Ash));
}
@@ -159,7 +167,8 @@ contract Flopper {
bids[id].lot = lot;
bids[id].tic = add(uint48(now), ttl);
}
- function deal(uint id) external {
+
+ function deal(uint256 id) external {
require(live == 1, "Flopper/not-live");
require(bids[id].tic != 0 && (bids[id].tic < now || bids[id].end < now), "Flopper/not-finished");
gem.mint(bids[id].guy, bids[id].lot);
@@ -168,10 +177,11 @@ contract Flopper {
// --- Shutdown ---
function cage() external auth {
- live = 0;
- vow = msg.sender;
+ live = 0;
+ vow = msg.sender;
}
- function yank(uint id) external {
+
+ function yank(uint256 id) external {
require(live == 0, "Flopper/still-live");
require(bids[id].guy != address(0), "Flopper/guy-not-set");
vat.suck(vow, bids[id].guy, bids[id].bid);
diff --git a/src/join.sol b/src/join.sol
index 42b01c91..86055979 100644
--- a/src/join.sol
+++ b/src/join.sol
@@ -24,19 +24,19 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface GemLike {
- function decimals() external view returns (uint);
- function transfer(address,uint) external returns (bool);
- function transferFrom(address,address,uint) external returns (bool);
+ function decimals() external view returns (uint256);
+ function transfer(address, uint256) external returns (bool);
+ function transferFrom(address, address, uint256) external returns (bool);
}
interface DSTokenLike {
- function mint(address,uint) external;
- function burn(address,uint) external;
+ function mint(address, uint256) external;
+ function burn(address, uint256) external;
}
interface VatLike {
- function slip(bytes32,address,int) external;
- function move(address,address,uint) external;
+ function slip(bytes32, address, int256) external;
+ function move(address, address, uint256) external;
}
/*
@@ -65,25 +65,27 @@ interface VatLike {
contract GemJoin {
// --- Auth ---
- mapping (address => uint) public wards;
+ mapping(address => uint256) public wards;
+
function rely(address usr) external auth {
wards[usr] = 1;
emit Rely(usr);
}
+
function deny(address usr) external auth {
wards[usr] = 0;
emit Deny(usr);
}
- modifier auth {
+ modifier auth() {
require(wards[msg.sender] == 1, "GemJoin/not-authorized");
_;
}
- VatLike public vat; // CDP Engine
- bytes32 public ilk; // Collateral Type
+ VatLike public vat; // CDP Engine
+ bytes32 public ilk; // Collateral Type
GemLike public gem;
- uint public dec;
- uint public live; // Active Flag
+ uint256 public dec;
+ uint256 public live; // Active Flag
// Events
event Rely(address indexed usr);
@@ -101,20 +103,23 @@ contract GemJoin {
dec = gem.decimals();
emit Rely(msg.sender);
}
+
function cage() external auth {
live = 0;
emit Cage();
}
- function join(address usr, uint wad) external {
+
+ function join(address usr, uint256 wad) external {
require(live == 1, "GemJoin/not-live");
- require(int(wad) >= 0, "GemJoin/overflow");
- vat.slip(ilk, usr, int(wad));
+ require(int256(wad) >= 0, "GemJoin/overflow");
+ vat.slip(ilk, usr, int256(wad));
require(gem.transferFrom(msg.sender, address(this), wad), "GemJoin/failed-transfer");
emit Join(usr, wad);
}
- function exit(address usr, uint wad) external {
+
+ function exit(address usr, uint256 wad) external {
require(wad <= 2 ** 255, "GemJoin/overflow");
- vat.slip(ilk, msg.sender, -int(wad));
+ vat.slip(ilk, msg.sender, -int256(wad));
require(gem.transfer(usr, wad), "GemJoin/failed-transfer");
emit Exit(usr, wad);
}
@@ -122,23 +127,25 @@ contract GemJoin {
contract DaiJoin {
// --- Auth ---
- mapping (address => uint) public wards;
+ mapping(address => uint256) public wards;
+
function rely(address usr) external auth {
wards[usr] = 1;
emit Rely(usr);
}
+
function deny(address usr) external auth {
wards[usr] = 0;
emit Deny(usr);
}
- modifier auth {
+ modifier auth() {
require(wards[msg.sender] == 1, "DaiJoin/not-authorized");
_;
}
- VatLike public vat; // CDP Engine
- DSTokenLike public dai; // Stablecoin Token
- uint public live; // Active Flag
+ VatLike public vat; // CDP Engine
+ DSTokenLike public dai; // Stablecoin Token
+ uint256 public live; // Active Flag
// Events
event Rely(address indexed usr);
@@ -153,20 +160,24 @@ contract DaiJoin {
vat = VatLike(vat_);
dai = DSTokenLike(dai_);
}
+
function cage() external auth {
live = 0;
emit Cage();
}
- uint constant ONE = 10 ** 27;
- function mul(uint x, uint y) internal pure returns (uint z) {
+ uint256 constant ONE = 10 ** 27;
+
+ function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
- function join(address usr, uint wad) external {
+
+ function join(address usr, uint256 wad) external {
vat.move(address(this), usr, mul(ONE, wad));
dai.burn(msg.sender, wad);
emit Join(usr, wad);
}
- function exit(address usr, uint wad) external {
+
+ function exit(address usr, uint256 wad) external {
require(live == 1, "DaiJoin/not-live");
vat.move(msg.sender, address(this), mul(ONE, wad));
dai.mint(usr, wad);
diff --git a/src/jug.sol b/src/jug.sol
index dae9b263..5c24e9f1 100644
--- a/src/jug.sol
+++ b/src/jug.sol
@@ -24,33 +24,41 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface VatLike {
- function ilks(bytes32) external returns (
- uint256 Art, // [wad]
- uint256 rate // [ray]
- );
- function fold(bytes32,address,int) external;
+ function ilks(bytes32)
+ external
+ returns (
+ uint256 Art, // [wad]
+ uint256 rate // [ray]
+ );
+ function fold(bytes32, address, int256) external;
}
contract Jug {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address usr) external auth { wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Jug/not-authorized");
_;
}
// --- Data ---
struct Ilk {
- uint256 duty; // Collateral-specific, per-second stability fee contribution [ray]
- uint256 rho; // Time of last drip [unix epoch time]
+ uint256 duty; // Collateral-specific, per-second stability fee contribution [ray]
+ uint256 rho; // Time of last drip [unix epoch time]
}
- mapping (bytes32 => Ilk) public ilks;
- VatLike public vat; // CDP Engine
- address public vow; // Debt Engine
- uint256 public base; // Global, per-second stability fee contribution [ray]
+ mapping(bytes32 => Ilk) public ilks;
+ VatLike public vat; // CDP Engine
+ address public vow; // Debt Engine
+ uint256 public base; // Global, per-second stability fee contribution [ray]
// --- Init ---
constructor(address vat_) public {
@@ -59,39 +67,49 @@ contract Jug {
}
// --- Math ---
- function _rpow(uint x, uint n, uint b) internal pure returns (uint z) {
- assembly {
- switch x case 0 {switch n case 0 {z := b} default {z := 0}}
- default {
- switch mod(n, 2) case 0 { z := b } default { z := x }
- let half := div(b, 2) // for rounding.
- for { n := div(n, 2) } n { n := div(n,2) } {
- let xx := mul(x, x)
- if iszero(eq(div(xx, x), x)) { revert(0,0) }
- let xxRound := add(xx, half)
- if lt(xxRound, xx) { revert(0,0) }
- x := div(xxRound, b)
- if mod(n,2) {
- let zx := mul(z, x)
- if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
- let zxRound := add(zx, half)
- if lt(zxRound, zx) { revert(0,0) }
- z := div(zxRound, b)
+ function _rpow(uint256 x, uint256 n, uint256 b) internal pure returns (uint256 z) {
+ assembly {
+ switch x
+ case 0 {
+ switch n
+ case 0 { z := b }
+ default { z := 0 }
+ }
+ default {
+ switch mod(n, 2)
+ case 0 { z := b }
+ default { z := x }
+ let half := div(b, 2) // for rounding.
+ for { n := div(n, 2) } n { n := div(n, 2) } {
+ let xx := mul(x, x)
+ if iszero(eq(div(xx, x), x)) { revert(0, 0) }
+ let xxRound := add(xx, half)
+ if lt(xxRound, xx) { revert(0, 0) }
+ x := div(xxRound, b)
+ if mod(n, 2) {
+ let zx := mul(z, x)
+ if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) }
+ let zxRound := add(zx, half)
+ if lt(zxRound, zx) { revert(0, 0) }
+ z := div(zxRound, b)
+ }
+ }
}
- }
}
- }
}
uint256 constant ONE = 10 ** 27;
- function _add(uint x, uint y) internal pure returns (uint z) {
+
+ function _add(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x + y;
require(z >= x);
}
- function _diff(uint x, uint y) internal pure returns (int z) {
- z = int(x) - int(y);
- require(int(x) >= 0 && int(y) >= 0);
+
+ function _diff(uint256 x, uint256 y) internal pure returns (int256 z) {
+ z = int256(x) - int256(y);
+ require(int256(x) >= 0 && int256(y) >= 0);
}
- function _rmul(uint x, uint y) internal pure returns (uint z) {
+
+ function _rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
require(y == 0 || z / y == x);
z = z / ONE;
@@ -102,26 +120,29 @@ contract Jug {
Ilk storage i = ilks[ilk];
require(i.duty == 0, "Jug/ilk-already-init");
i.duty = ONE;
- i.rho = now;
+ i.rho = now;
}
- function file(bytes32 ilk, bytes32 what, uint data) external auth {
+
+ function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
require(now == ilks[ilk].rho, "Jug/rho-not-updated");
if (what == "duty") ilks[ilk].duty = data;
else revert("Jug/file-unrecognized-param");
}
- function file(bytes32 what, uint data) external auth {
+
+ function file(bytes32 what, uint256 data) external auth {
if (what == "base") base = data;
else revert("Jug/file-unrecognized-param");
}
+
function file(bytes32 what, address data) external auth {
if (what == "vow") vow = data;
else revert("Jug/file-unrecognized-param");
}
// --- Stability Fee Collection ---
- function drip(bytes32 ilk) external returns (uint rate) {
+ function drip(bytes32 ilk) external returns (uint256 rate) {
require(now >= ilks[ilk].rho, "Jug/invalid-now");
- (, uint prev) = vat.ilks(ilk);
+ (, uint256 prev) = vat.ilks(ilk);
rate = _rmul(_rpow(_add(base, ilks[ilk].duty), now - ilks[ilk].rho, ONE), prev);
vat.fold(ilk, vow, _diff(rate, prev));
ilks[ilk].rho = now;
diff --git a/src/pot.sol b/src/pot.sol
index cae58cda..2b2a9452 100644
--- a/src/pot.sol
+++ b/src/pot.sol
@@ -43,32 +43,38 @@ pragma solidity ^0.6.12;
*/
interface VatLike {
- function move(address,address,uint256) external;
- function suck(address,address,uint256) external;
+ function move(address, address, uint256) external;
+ function suck(address, address, uint256) external;
}
contract Pot {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address guy) external auth { wards[guy] = 1; }
- function deny(address guy) external auth { wards[guy] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address guy) external auth {
+ wards[guy] = 1;
+ }
+
+ function deny(address guy) external auth {
+ wards[guy] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Pot/not-authorized");
_;
}
// --- Data ---
- mapping (address => uint256) public pie; // Normalised Savings Dai [wad]
+ mapping(address => uint256) public pie; // Normalised Savings Dai [wad]
- uint256 public Pie; // Total Normalised Savings Dai [wad]
- uint256 public dsr; // The Dai Savings Rate [ray]
- uint256 public chi; // The Rate Accumulator [ray]
+ uint256 public Pie; // Total Normalised Savings Dai [wad]
+ uint256 public dsr; // The Dai Savings Rate [ray]
+ uint256 public chi; // The Rate Accumulator [ray]
- VatLike public vat; // CDP Engine
- address public vow; // Debt Engine
- uint256 public rho; // Time of last drip [unix epoch time]
+ VatLike public vat; // CDP Engine
+ address public vow; // Debt Engine
+ uint256 public rho; // Time of last drip [unix epoch time]
- uint256 public live; // Active Flag
+ uint256 public live; // Active Flag
// --- Init ---
constructor(address vat_) public {
@@ -82,23 +88,31 @@ contract Pot {
// --- Math ---
uint256 constant ONE = 10 ** 27;
- function _rpow(uint x, uint n, uint base) internal pure returns (uint z) {
+
+ function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {
assembly {
- switch x case 0 {switch n case 0 {z := base} default {z := 0}}
+ switch x
+ case 0 {
+ switch n
+ case 0 { z := base }
+ default { z := 0 }
+ }
default {
- switch mod(n, 2) case 0 { z := base } default { z := x }
- let half := div(base, 2) // for rounding.
- for { n := div(n, 2) } n { n := div(n,2) } {
+ switch mod(n, 2)
+ case 0 { z := base }
+ default { z := x }
+ let half := div(base, 2) // for rounding.
+ for { n := div(n, 2) } n { n := div(n, 2) } {
let xx := mul(x, x)
- if iszero(eq(div(xx, x), x)) { revert(0,0) }
+ if iszero(eq(div(xx, x), x)) { revert(0, 0) }
let xxRound := add(xx, half)
- if lt(xxRound, xx) { revert(0,0) }
+ if lt(xxRound, xx) { revert(0, 0) }
x := div(xxRound, base)
- if mod(n,2) {
+ if mod(n, 2) {
let zx := mul(z, x)
- if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
+ if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0, 0) }
let zxRound := add(zx, half)
- if lt(zxRound, zx) { revert(0,0) }
+ if lt(zxRound, zx) { revert(0, 0) }
z := div(zxRound, base)
}
}
@@ -106,19 +120,19 @@ contract Pot {
}
}
- function _rmul(uint x, uint y) internal pure returns (uint z) {
+ function _rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = _mul(x, y) / ONE;
}
- function _add(uint x, uint y) internal pure returns (uint z) {
+ function _add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
- function _sub(uint x, uint y) internal pure returns (uint z) {
+ function _sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
- function _mul(uint x, uint y) internal pure returns (uint z) {
+ function _mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -141,26 +155,26 @@ contract Pot {
}
// --- Savings Rate Accumulation ---
- function drip() external returns (uint tmp) {
+ function drip() external returns (uint256 tmp) {
require(now >= rho, "Pot/invalid-now");
tmp = _rmul(_rpow(dsr, now - rho, ONE), chi);
- uint chi_ = _sub(tmp, chi);
+ uint256 chi_ = _sub(tmp, chi);
chi = tmp;
rho = now;
vat.suck(address(vow), address(this), _mul(Pie, chi_));
}
// --- Savings Dai Management ---
- function join(uint wad) external {
+ function join(uint256 wad) external {
require(now == rho, "Pot/rho-not-updated");
pie[msg.sender] = _add(pie[msg.sender], wad);
- Pie = _add(Pie, wad);
+ Pie = _add(Pie, wad);
vat.move(msg.sender, address(this), _mul(chi, wad));
}
- function exit(uint wad) external {
+ function exit(uint256 wad) external {
pie[msg.sender] = _sub(pie[msg.sender], wad);
- Pie = _sub(Pie, wad);
+ Pie = _sub(Pie, wad);
vat.move(address(this), msg.sender, _mul(chi, wad));
}
}
diff --git a/src/spot.sol b/src/spot.sol
index 2f5b98d9..85d7bedd 100644
--- a/src/spot.sol
+++ b/src/spot.sol
@@ -22,7 +22,7 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface VatLike {
- function file(bytes32, bytes32, uint) external;
+ function file(bytes32, bytes32, uint256) external;
}
interface PipLike {
@@ -31,32 +31,38 @@ interface PipLike {
contract Spotter {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address guy) external auth { wards[guy] = 1; }
- function deny(address guy) external auth { wards[guy] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address guy) external auth {
+ wards[guy] = 1;
+ }
+
+ function deny(address guy) external auth {
+ wards[guy] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Spotter/not-authorized");
_;
}
// --- Data ---
struct Ilk {
- PipLike pip; // Price Feed
- uint256 mat; // Liquidation ratio [ray]
+ PipLike pip; // Price Feed
+ uint256 mat; // Liquidation ratio [ray]
}
- mapping (bytes32 => Ilk) public ilks;
+ mapping(bytes32 => Ilk) public ilks;
- VatLike public vat; // CDP Engine
- uint256 public par; // ref per dai [ray]
+ VatLike public vat; // CDP Engine
+ uint256 public par; // ref per dai [ray]
uint256 public live;
// --- Events ---
event Poke(
- bytes32 ilk,
- bytes32 val, // [wad]
- uint256 spot // [ray]
+ bytes32 ilk,
+ bytes32 val, // [wad]
+ uint256 spot // [ray]
);
// --- Init ---
@@ -68,12 +74,13 @@ contract Spotter {
}
// --- Math ---
- uint constant ONE = 10 ** 27;
+ uint256 constant ONE = 10 ** 27;
- function mul(uint x, uint y) internal pure returns (uint z) {
+ function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
- function rdiv(uint x, uint y) internal pure returns (uint z) {
+
+ function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, ONE) / y;
}
@@ -83,12 +90,14 @@ contract Spotter {
if (what == "pip") ilks[ilk].pip = PipLike(pip_);
else revert("Spotter/file-unrecognized-param");
}
- function file(bytes32 what, uint data) external auth {
+
+ function file(bytes32 what, uint256 data) external auth {
require(live == 1, "Spotter/not-live");
if (what == "par") par = data;
else revert("Spotter/file-unrecognized-param");
}
- function file(bytes32 ilk, bytes32 what, uint data) external auth {
+
+ function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
require(live == 1, "Spotter/not-live");
if (what == "mat") ilks[ilk].mat = data;
else revert("Spotter/file-unrecognized-param");
@@ -97,7 +106,7 @@ contract Spotter {
// --- Update value ---
function poke(bytes32 ilk) external {
(bytes32 val, bool has) = ilks[ilk].pip.peek();
- uint256 spot = has ? rdiv(rdiv(mul(uint(val), 10 ** 9), par), ilks[ilk].mat) : 0;
+ uint256 spot = has ? rdiv(rdiv(mul(uint256(val), 10 ** 9), par), ilks[ilk].mat) : 0;
vat.file(ilk, "spot", spot);
emit Poke(ilk, val, spot);
}
diff --git a/src/test/abaci.t.sol b/src/test/abaci.t.sol
index 08838464..0f4cd541 100644
--- a/src/test/abaci.t.sol
+++ b/src/test/abaci.t.sol
@@ -25,7 +25,7 @@ import "../abaci.sol";
interface Hevm {
function warp(uint256) external;
- function store(address,bytes32,bytes32) external;
+ function store(address, bytes32, bytes32) external;
}
contract ClipperTest is DSTest {
@@ -34,8 +34,7 @@ contract ClipperTest is DSTest {
uint256 RAY = 10 ** 27;
// CHEAT_CODE = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D
- bytes20 constant CHEAT_CODE =
- bytes20(uint160(uint256(keccak256('hevm cheat code'))));
+ bytes20 constant CHEAT_CODE = bytes20(uint160(uint256(keccak256("hevm cheat code"))));
uint256 constant startTime = 604411200; // Used to avoid issues with `now`
@@ -44,17 +43,14 @@ contract ClipperTest is DSTest {
hevm.warp(startTime);
}
- function assertEqWithinTolerance(
- uint256 x,
- uint256 y,
- uint256 tolerance) internal {
- uint256 diff;
- if (x >= y) {
- diff = x - y;
- } else {
- diff = y - x;
- }
- assertTrue(diff <= tolerance);
+ function assertEqWithinTolerance(uint256 x, uint256 y, uint256 tolerance) internal {
+ uint256 diff;
+ if (x >= y) {
+ diff = x - y;
+ } else {
+ diff = y - x;
+ }
+ assertTrue(diff <= tolerance);
}
function checkExpDecrease(
@@ -66,26 +62,24 @@ contract ClipperTest is DSTest {
uint256 percentDecrease,
uint256 testTime,
uint256 tolerance
- )
- public
- {
+ ) public {
uint256 price;
uint256 lastPrice;
uint256 testPrice;
hevm.warp(startTime);
calc.file(bytes32("step"), step);
- calc.file(bytes32("cut"), cut);
+ calc.file(bytes32("cut"), cut);
price = calc.price(top, now - tic);
assertEq(price, top);
- for(uint256 i = 1; i < testTime; i += 1) {
+ for (uint256 i = 1; i < testTime; i += 1) {
hevm.warp(startTime + i);
lastPrice = price;
price = calc.price(top, now - tic);
// Stairstep calculation
- if (i % step == 0) { testPrice = lastPrice * percentDecrease / RAY; }
- else { testPrice = lastPrice; }
+ if (i % step == 0) testPrice = lastPrice * percentDecrease / RAY;
+ else testPrice = lastPrice;
assertEqWithinTolerance(testPrice, price, tolerance);
}
}
@@ -97,66 +91,64 @@ contract ClipperTest is DSTest {
uint256 step;
uint256 testTime = 10 minutes;
-
/*** Extreme high collateral price ($50m) ***/
uint256 tolerance = 100000000; // Tolerance scales with price
- uint256 top = 50000000 * RAY;
+ uint256 top = 50000000 * RAY;
// 1.1234567890% decrease every 1 second
// TODO: Check if there's a cleaner way to do this. I was getting rational_const errors.
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 1;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 2.1234567890% decrease every 1 second
- percentDecrease = RAY - 2.1234567890E27 / 100;
+ percentDecrease = RAY - 2.123456789e27 / 100;
step = 1;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 1.1234567890% decrease every 5 seconds
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 5;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 2.1234567890% decrease every 5 seconds
- percentDecrease = RAY - 2.1234567890E27 / 100;
+ percentDecrease = RAY - 2.123456789e27 / 100;
step = 5;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 1.1234567890% decrease every 5 minutes
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 5 minutes;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
-
/*** Extreme low collateral price ($0.0000001) ***/
tolerance = 1; // Lowest tolerance is 1e-27
top = 1 * RAY / 10000000;
// 1.1234567890% decrease every 1 second
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 1;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 2.1234567890% decrease every 1 second
- percentDecrease = RAY - 2.1234567890E27 / 100;
+ percentDecrease = RAY - 2.123456789e27 / 100;
step = 1;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 1.1234567890% decrease every 5 seconds
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 5;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 2.1234567890% decrease every 5 seconds
- percentDecrease = RAY - 2.1234567890E27 / 100;
+ percentDecrease = RAY - 2.123456789e27 / 100;
step = 5;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
// 1.1234567890% decrease every 5 minutes
- percentDecrease = RAY - 1.1234567890E27 / 100;
+ percentDecrease = RAY - 1.123456789e27 / 100;
step = 5 minutes;
checkExpDecrease(calc, percentDecrease, step, top, tic, percentDecrease, testTime, tolerance);
}
@@ -164,14 +156,16 @@ contract ClipperTest is DSTest {
function test_continuous_exp_decrease() public {
ExponentialDecrease calc = new ExponentialDecrease();
uint256 tHalf = 900;
- uint256 cut = 0.999230132966E27; // ~15 half life, cut ~= e^(ln(1/2)/900)
+ uint256 cut = 0.999230132966e27; // ~15 half life, cut ~= e^(ln(1/2)/900)
calc.file("cut", cut);
uint256 top = 4000 * RAY;
uint256 expectedPrice = top;
- uint256 tolerance = RAY / 1000; // 0.001, i.e 0.1%
- for (uint256 i = 0; i < 5; i++) { // will cover initial value + four half-lives
- assertEqWithinTolerance(calc.price(top, i*tHalf), expectedPrice, tolerance);
+ uint256 tolerance = RAY / 1000; // 0.001, i.e 0.1%
+
+ // Made a for loop modification here!!
+ for (uint256 i = 0; i < 5; i++) {
+ assertEqWithinTolerance(calc.price(top, i * tHalf), expectedPrice, tolerance);
// each loop iteration advances one half-life, so expectedPrice decreases by a factor of 2
expectedPrice /= 2;
}
@@ -187,43 +181,43 @@ contract ClipperTest is DSTest {
uint256 price = calc.price(top, now - tic);
assertEq(price, top);
- hevm.warp(startTime + 360); // 6min in, 1/10 done
+ hevm.warp(startTime + 360); // 6min in, 1/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100) * RAY);
- hevm.warp(startTime + 360 * 2); // 12min in, 2/10 done
+ hevm.warp(startTime + 360 * 2); // 12min in, 2/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 2) * RAY);
- hevm.warp(startTime + 360 * 3); // 18min in, 3/10 done
+ hevm.warp(startTime + 360 * 3); // 18min in, 3/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 3) * RAY);
- hevm.warp(startTime + 360 * 4); // 24min in, 4/10 done
+ hevm.warp(startTime + 360 * 4); // 24min in, 4/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 4) * RAY);
- hevm.warp(startTime + 360 * 5); // 30min in, 5/10 done
+ hevm.warp(startTime + 360 * 5); // 30min in, 5/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 5) * RAY);
- hevm.warp(startTime + 360 * 6); // 36min in, 6/10 done
+ hevm.warp(startTime + 360 * 6); // 36min in, 6/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 6) * RAY);
- hevm.warp(startTime + 360 * 7); // 42min in, 7/10 done
+ hevm.warp(startTime + 360 * 7); // 42min in, 7/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 7) * RAY);
- hevm.warp(startTime + 360 * 8); // 48min in, 8/10 done
+ hevm.warp(startTime + 360 * 8); // 48min in, 8/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 8) * RAY);
- hevm.warp(startTime + 360 * 9); // 54min in, 9/10 done
+ hevm.warp(startTime + 360 * 9); // 54min in, 9/10 done
price = calc.price(top, now - tic);
assertEq(price, (1000 - 100 * 9) * RAY);
- hevm.warp(startTime + 360 * 10); // 60min in, 10/10 done
+ hevm.warp(startTime + 360 * 10); // 60min in, 10/10 done
price = calc.price(top, now - tic);
assertEq(price, 0);
}
diff --git a/src/test/clip.t.sol b/src/test/clip.t.sol
index 3eeef243..cb5f8329 100644
--- a/src/test/clip.t.sol
+++ b/src/test/clip.t.sol
@@ -23,9 +23,9 @@ import "ds-test/test.sol";
import "ds-token/token.sol";
import "ds-value/value.sol";
-import {Vat} from "../vat.sol";
+import {Vat} from "../vat.sol";
import {Spotter} from "../spot.sol";
-import {Vow} from "../vow.sol";
+import {Vow} from "../vow.sol";
import {GemJoin, DaiJoin} from "../join.sol";
import {Clipper} from "../clip.sol";
@@ -34,11 +34,10 @@ import "../dog.sol";
interface Hevm {
function warp(uint256) external;
- function store(address,bytes32,bytes32) external;
+ function store(address, bytes32, bytes32) external;
}
contract Exchange {
-
DSToken gold;
DSToken dai;
uint256 goldPrice;
@@ -51,13 +50,12 @@ contract Exchange {
function sellGold(uint256 goldAmt) external {
gold.transferFrom(msg.sender, address(this), goldAmt);
- uint256 daiAmt = goldAmt * goldPrice / 1E18;
+ uint256 daiAmt = goldAmt * goldPrice / 1e18;
dai.transfer(msg.sender, daiAmt);
}
}
contract Trader {
-
Clipper clip;
Vat vat;
DSToken gold;
@@ -84,33 +82,18 @@ contract Trader {
exchange = exchange_;
}
- function take(
- uint256 id,
- uint256 amt,
- uint256 max,
- address who,
- bytes calldata data
- )
- external
- {
- clip.take({
- id: id,
- amt: amt,
- max: max,
- who: who,
- data: data
- });
+ function take(uint256 id, uint256 amt, uint256 max, address who, bytes calldata data) external {
+ clip.take({id: id, amt: amt, max: max, who: who, data: data});
}
- function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data)
- external {
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
data;
goldJoin.exit(address(this), slice);
gold.approve(address(exchange));
exchange.sellGold(slice);
dai.approve(address(daiJoin));
vat.hope(address(clip));
- daiJoin.join(sender, owe / 1E27);
+ daiJoin.join(sender, owe / 1e27);
}
}
@@ -125,22 +108,8 @@ contract Guy {
Vat(address(clip.vat())).hope(usr);
}
- function take(
- uint256 id,
- uint256 amt,
- uint256 max,
- address who,
- bytes calldata data
- )
- external
- {
- clip.take({
- id: id,
- amt: amt,
- max: max,
- who: who,
- data: data
- });
+ function take(uint256 id, uint256 amt, uint256 max, address who, bytes calldata data) external {
+ clip.take({id: id, amt: amt, max: max, who: who, data: data});
}
function bark(Dog dog, bytes32 ilk, address urn, address usr) external {
@@ -149,16 +118,17 @@ contract Guy {
}
contract BadGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data)
- external {
- sender; owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ sender;
+ owe;
+ slice;
+ data;
clip.take({ // attempt reentrancy
id: 1,
amt: 25 ether,
- max: 5 ether * 10E27,
+ max: 5 ether * 10e27,
who: address(this),
data: ""
});
@@ -166,67 +136,65 @@ contract BadGuy is Guy {
}
contract RedoGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(
- address sender, uint256 owe, uint256 slice, bytes calldata data
- ) external {
- owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ owe;
+ slice;
+ data;
clip.redo(1, sender);
}
}
contract KickGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(
- address sender, uint256 owe, uint256 slice, bytes calldata data
- ) external {
- sender; owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ sender;
+ owe;
+ slice;
+ data;
clip.kick(1, 1, address(0), address(0));
}
}
contract FileUintGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(
- address sender, uint256 owe, uint256 slice, bytes calldata data
- ) external {
- sender; owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ sender;
+ owe;
+ slice;
+ data;
clip.file("stopped", 1);
}
}
contract FileAddrGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(
- address sender, uint256 owe, uint256 slice, bytes calldata data
- ) external {
- sender; owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ sender;
+ owe;
+ slice;
+ data;
clip.file("vow", address(123));
}
}
contract YankGuy is Guy {
+ constructor(Clipper clip_) public Guy(clip_) {}
- constructor(Clipper clip_) Guy(clip_) public {}
-
- function clipperCall(
- address sender, uint256 owe, uint256 slice, bytes calldata data
- ) external {
- sender; owe; slice; data;
+ function clipperCall(address sender, uint256 owe, uint256 slice, bytes calldata data) external {
+ sender;
+ owe;
+ slice;
+ data;
clip.yank(1);
}
}
contract PublicClip is Clipper {
-
constructor(address vat, address spot, address dog, bytes32 ilk) public Clipper(vat, spot, dog, ilk) {}
function add() public returns (uint256 id) {
@@ -243,10 +211,10 @@ contract PublicClip is Clipper {
contract ClipperTest is DSTest {
Hevm hevm;
- Vat vat;
- Dog dog;
+ Vat vat;
+ Dog dog;
Spotter spot;
- Vow vow;
+ Vow vow;
DSValue pip;
DSToken gold;
GemJoin goldJoin;
@@ -267,8 +235,7 @@ contract ClipperTest is DSTest {
uint256 RAD = 10 ** 45;
// CHEAT_CODE = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D
- bytes20 constant CHEAT_CODE =
- bytes20(uint160(uint256(keccak256('hevm cheat code'))));
+ bytes20 constant CHEAT_CODE = bytes20(uint160(uint256(keccak256("hevm cheat code"))));
bytes32 constant ilk = "gold";
uint256 constant goldPrice = 5 ether;
@@ -283,29 +250,30 @@ contract ClipperTest is DSTest {
(uint256 ink_,) = vat.urns(ilk_, urn_);
return ink_;
}
+
function _art(bytes32 ilk_, address urn_) internal view returns (uint256) {
- (,uint256 art_) = vat.urns(ilk_, urn_);
+ (, uint256 art_) = vat.urns(ilk_, urn_);
return art_;
}
- modifier takeSetup {
+ modifier takeSetup() {
uint256 pos;
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
StairstepExponentialDecrease calc = new StairstepExponentialDecrease();
- calc.file("cut", RAY - ray(0.01 ether)); // 1% decrease
- calc.file("step", 1); // Decrease every 1 second
+ calc.file("cut", RAY - ray(0.01 ether)); // 1% decrease
+ calc.file("step", 1); // Decrease every 1 second
- clip.file("buf", ray(1.25 ether)); // 25% Initial price buffer
- clip.file("calc", address(calc)); // File price contract
- clip.file("cusp", ray(0.3 ether)); // 70% drop before reset
- clip.file("tail", 3600); // 1 hour before reset
+ clip.file("buf", ray(1.25 ether)); // 25% Initial price buffer
+ clip.file("calc", address(calc)); // File price contract
+ clip.file("cusp", ray(0.3 ether)); // 70% drop before reset
+ clip.file("tail", 3600); // 1 hour before reset
(ink, art) = vat.urns(ilk, me);
assertEq(ink, 40 ether);
@@ -338,9 +306,11 @@ contract ClipperTest is DSTest {
function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
+
function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -389,7 +359,7 @@ contract ClipperTest is DSTest {
vat.file(ilk, "dust", rad(20 ether)); // $20 dust
vat.file(ilk, "line", rad(10000 ether));
- vat.file("Line", rad(10000 ether));
+ vat.file("Line", rad(10000 ether));
dog.file(ilk, "chop", 1.1 ether); // 10% chop
dog.file(ilk, "hole", rad(1000 ether));
@@ -411,7 +381,7 @@ contract ClipperTest is DSTest {
assertEq(vat.dai(me), rad(100 ether));
pip.poke(bytes32(uint256(4 ether))); // Spot = $2
- spot.poke(ilk); // Now unsafe
+ spot.poke(ilk); // Now unsafe
ali = address(new Guy(clip));
bob = address(new Guy(clip));
@@ -422,8 +392,8 @@ contract ClipperTest is DSTest {
Guy(bob).hope(address(clip));
vat.suck(address(0), address(this), rad(1000 ether));
- vat.suck(address(0), address(ali), rad(1000 ether));
- vat.suck(address(0), address(bob), rad(1000 ether));
+ vat.suck(address(0), address(ali), rad(1000 ether));
+ vat.suck(address(0), address(bob), rad(1000 ether));
}
function test_change_dog() public {
@@ -443,13 +413,13 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
- clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
- clip.file("chip", 0); // No linear increase
+ clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
+ clip.file("chip", 0); // No linear increase
assertEq(clip.kicks(), 0);
(pos, tab, lot, usr, tic, top) = clip.sales(1);
@@ -482,13 +452,13 @@ contract ClipperTest is DSTest {
assertEq(art, 0 ether);
pip.poke(bytes32(goldPrice)); // Spot = $2.5
- spot.poke(ilk); // Now safe
+ spot.poke(ilk); // Now safe
hevm.warp(startTime + 100);
vat.frob(ilk, me, me, me, 40 ether, 100 ether);
pip.poke(bytes32(uint256(4 ether))); // Spot = $2
- spot.poke(ilk); // Now unsafe
+ spot.poke(ilk); // Now unsafe
(pos, tab, lot, usr, tic, top) = clip.sales(2);
assertEq(pos, 0);
@@ -499,10 +469,10 @@ contract ClipperTest is DSTest {
assertEq(top, 0);
assertEq(vat.gem(ilk, me), 920 ether);
- clip.file(bytes32("buf"), ray(1.25 ether)); // 25% Initial price buffer
+ clip.file(bytes32("buf"), ray(1.25 ether)); // 25% Initial price buffer
- clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
- clip.file("chip", 0.02 ether); // Linear increase of 2% of tab
+ clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
+ clip.file("chip", 0.02 ether); // Linear increase of 2% of tab
assertEq(vat.dai(bob), rad(1000 ether));
@@ -571,7 +541,7 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
@@ -613,7 +583,7 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
@@ -655,7 +625,7 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
@@ -664,9 +634,9 @@ contract ClipperTest is DSTest {
(, uint256 rate,,,) = vat.ilks(ilk);
assertEq(rate, ray(1.02 ether));
- dog.file(ilk, "hole", 100 * RAD); // Makes room = 100 RAD
- dog.file(ilk, "chop", 1 ether); // 0% chop for precise calculations
- vat.file(ilk, "dust", 20 * RAD); // 20 DAI minimum Vault debt
+ dog.file(ilk, "hole", 100 * RAD); // Makes room = 100 RAD
+ dog.file(ilk, "chop", 1 ether); // 0% chop for precise calculations
+ vat.file(ilk, "dust", 20 * RAD); // 20 DAI minimum Vault debt
clip.upchost();
assertEq(clip.kicks(), 0);
@@ -680,7 +650,7 @@ contract ClipperTest is DSTest {
assertEq(vat.gem(ilk, me), 960 ether);
(ink, art) = vat.urns(ilk, me);
assertEq(ink, 40 ether);
- assertEq(art, 100 ether); // Full debt is 102 DAI since rate = 1.02 * RAY
+ assertEq(art, 100 ether); // Full debt is 102 DAI since rate = 1.02 * RAY
// (art - dart) * rate ~= 2 RAD < dust = 20 RAD
// => remnant would be dusty, so a full liquidation occurs.
@@ -689,7 +659,7 @@ contract ClipperTest is DSTest {
assertEq(clip.kicks(), 1);
(pos, tab, lot, usr, tic, top) = clip.sales(1);
assertEq(pos, 0);
- assertEq(tab, mul(100 ether, rate)); // No chop
+ assertEq(tab, mul(100 ether, rate)); // No chop
assertEq(lot, 40 ether);
assertEq(usr, me);
assertEq(uint256(tic), now);
@@ -705,7 +675,7 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
@@ -714,9 +684,9 @@ contract ClipperTest is DSTest {
(, uint256 rate,,,) = vat.ilks(ilk);
assertEq(rate, ray(1.02 ether));
- dog.file(ilk, "hole", 816 * RAD / 10); // Makes room = 81.6 RAD => dart = 80
- dog.file(ilk, "chop", 1 ether); // 0% chop for precise calculations
- vat.file(ilk, "dust", 204 * RAD / 10); // 20.4 DAI dust
+ dog.file(ilk, "hole", 816 * RAD / 10); // Makes room = 81.6 RAD => dart = 80
+ dog.file(ilk, "chop", 1 ether); // 0% chop for precise calculations
+ vat.file(ilk, "dust", 204 * RAD / 10); // 20.4 DAI dust
clip.upchost();
assertEq(clip.kicks(), 0);
@@ -739,7 +709,7 @@ contract ClipperTest is DSTest {
assertEq(clip.kicks(), 1);
(pos, tab, lot, usr, tic, top) = clip.sales(1);
assertEq(pos, 0);
- assertEq(tab, 816 * RAD / 10); // Equal to ilk.hole
+ assertEq(tab, 816 * RAD / 10); // Equal to ilk.hole
assertEq(lot, 32 ether);
assertEq(usr, me);
assertEq(uint256(tic), now);
@@ -809,7 +779,7 @@ contract ClipperTest is DSTest {
assertEq(_art(ilk, me), 100 ether);
assertEq(dog.Dirt(), 0);
- (,uint256 chop,, uint256 dirt) = dog.ilks(ilk);
+ (, uint256 chop,, uint256 dirt) = dog.ilks(ilk);
assertEq(dirt, 0);
dog.bark(ilk, me, address(this));
@@ -836,7 +806,7 @@ contract ClipperTest is DSTest {
assertEq(_art(ilk, me), 100 ether);
assertEq(dog.Dirt(), 0);
- (,uint256 chop,, uint256 dirt) = dog.ilks(ilk);
+ (, uint256 chop,, uint256 dirt) = dog.ilks(ilk);
assertEq(dirt, 0);
dog.bark(ilk, me, address(this));
@@ -871,17 +841,11 @@ contract ClipperTest is DSTest {
function test_take_over_tab() public takeSetup {
// Bid so owe (= 25 * 5 = 125 RAD) > tab (= 110 RAD)
// Readjusts slice to be tab/top = 25
- Guy(ali).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(ali), data: ""});
- assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(890 ether)); // Didn't pay more than tab (110)
- assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
+ assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
// Assert auction ends
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
@@ -899,17 +863,11 @@ contract ClipperTest is DSTest {
function test_take_at_tab() public takeSetup {
// Bid so owe (= 22 * 5 = 110 RAD) == tab (= 110 RAD)
- Guy(ali).take({
- id: 1,
- amt: 22 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 22 ether, max: ray(5 ether), who: address(ali), data: ""});
- assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(890 ether)); // Paid full tab (110)
- assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
+ assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
// Assert auction ends
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
@@ -927,23 +885,24 @@ contract ClipperTest is DSTest {
function test_take_under_tab() public takeSetup {
// Bid so owe (= 11 * 5 = 55 RAD) < tab (= 110 RAD)
- Guy(ali).take({
- id: 1,
- amt: 11 ether, // Half of tab at $110
+ Guy(ali)
+ .take({
+ id: 1,
+ amt: 11 ether, // Half of tab at $110
max: ray(5 ether),
who: address(ali),
data: ""
});
- assertEq(vat.gem(ilk, ali), 11 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 11 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(945 ether)); // Paid half tab (55)
- assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
+ assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
// Assert auction DOES NOT end
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
assertEq(pos, 0);
- assertEq(tab, rad(55 ether)); // 110 - 5 * 11
- assertEq(lot, 29 ether); // 40 - 11
+ assertEq(tab, rad(55 ether)); // 110 - 5 * 11
+ assertEq(lot, 29 ether); // 40 - 11
assertEq(usr, me);
assertEq(uint256(tic), now);
assertEq(top, ray(5 ether));
@@ -954,19 +913,20 @@ contract ClipperTest is DSTest {
}
function test_take_full_lot_partial_tab() public takeSetup {
- hevm.warp(now + 69); // approx 50% price decline
+ hevm.warp(now + 69); // approx 50% price decline
// Bid to purchase entire lot less than tab (~2.5 * 40 ~= 100 < 110)
- Guy(ali).take({
- id: 1,
- amt: 40 ether, // purchase all collateral
+ Guy(ali)
+ .take({
+ id: 1,
+ amt: 40 ether, // purchase all collateral
max: ray(2.5 ether),
who: address(ali),
data: ""
});
- assertEq(vat.gem(ilk, ali), 40 ether); // Took entire lot
- assertTrue(sub(vat.dai(ali), rad(900 ether)) < rad(0.1 ether)); // Paid about 100 ether
- assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned
+ assertEq(vat.gem(ilk, ali), 40 ether); // Took entire lot
+ assertTrue(sub(vat.dai(ali), rad(900 ether)) < rad(0.1 ether)); // Paid about 100 ether
+ assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned
// Assert auction ends
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
@@ -985,13 +945,7 @@ contract ClipperTest is DSTest {
function testFail_take_bid_too_low() public takeSetup {
// Bid so max (= 4) < price (= top = 5) (fails with "Clipper/too-expensive")
- Guy(ali).take({
- id: 1,
- amt: 22 ether,
- max: ray(4 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 22 ether, max: ray(4 ether), who: address(ali), data: ""});
}
function test_take_bid_recalculates_due_to_chost_check() public takeSetup {
@@ -999,16 +953,17 @@ contract ClipperTest is DSTest {
assertEq(tab, rad(110 ether));
assertEq(lot, 40 ether);
- (, uint256 price,uint256 _lot, uint256 _tab) = clip.getStatus(1);
+ (, uint256 price, uint256 _lot, uint256 _tab) = clip.getStatus(1);
assertEq(_lot, lot);
assertEq(_tab, tab);
assertEq(price, ray(5 ether));
// Bid for an amount that would leave less than chost remaining tab--bid will be decreased
// to leave tab == chost post-execution.
- Guy(ali).take({
- id: 1,
- amt: 18 * WAD, // Costs 90 DAI at current price; 110 - 90 == 20 < 22 == chost
+ Guy(ali)
+ .take({
+ id: 1,
+ amt: 18 * WAD, // Costs 90 DAI at current price; 110 - 90 == 20 < 22 == chost
max: ray(5 ether),
who: address(ali),
data: ""
@@ -1031,13 +986,7 @@ contract ClipperTest is DSTest {
// Bid so owe (= (22 - 1wei) * 5 = 110 RAD - 1) < tab (= 110 RAD)
// 1 < 20 RAD => owe = 110 RAD - 20 RAD
- Guy(ali).take({
- id: 1,
- amt: 40 ether,
- max: ray(2.8 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 40 ether, max: ray(2.8 ether), who: address(ali), data: ""});
// 40 * 2.73 = 109.42...
// It means a very low amount of tab (< dust) would remain but doesn't matter
@@ -1051,29 +1000,25 @@ contract ClipperTest is DSTest {
(, uint256 price,,) = clip.getStatus(1);
assertEq(price, ray(5 ether));
- clip.take({
- id: 1,
- amt: 17.6 ether,
- max: ray(5 ether),
- who: address(this),
- data: ""
- });
+ clip.take({id: 1, amt: 17.6 ether, max: ray(5 ether), who: address(this), data: ""});
(, uint256 tab, uint256 lot,,,) = clip.sales(1);
assertEq(tab, rad(22 ether));
assertEq(lot, 22.4 ether);
assertTrue(!(tab > clip.chost()));
- assertTrue(!try_take({
- id: 1,
- amt: 1 ether, // partial purchase attempt when !(tab > chost)
- max: ray(5 ether),
- who: address(this),
- data: ""
- }));
+ assertTrue(
+ !try_take({
+ id: 1,
+ amt: 1 ether, // partial purchase attempt when !(tab > chost)
+ max: ray(5 ether),
+ who: address(this),
+ data: ""
+ })
+ );
clip.take({
- id: 1,
+ id: 1,
amt: tab / price, // This time take the whole tab
max: ray(5 ether),
who: address(this),
@@ -1086,27 +1031,21 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
// Bid so owe (= 10 * 5 = 50 RAD) < tab (= 110 RAD)
- Guy(ali).take({
- id: 1,
- amt: 10 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 10 ether, max: ray(5 ether), who: address(ali), data: ""});
- assertEq(vat.gem(ilk, ali), 10 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 10 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(950 ether)); // Paid some tab (50)
- assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
+ assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
// Assert auction DOES NOT end
(pos, tab, lot, usr, tic, top) = clip.sales(1);
assertEq(pos, 0);
- assertEq(tab, rad(60 ether)); // 110 - 5 * 10
- assertEq(lot, 30 ether); // 40 - 10
+ assertEq(tab, rad(60 ether)); // 110 - 5 * 10
+ assertEq(lot, 30 ether); // 40 - 10
assertEq(usr, me);
assertEq(uint256(tic), now);
assertEq(top, ray(5 ether));
@@ -1114,9 +1053,10 @@ contract ClipperTest is DSTest {
hevm.warp(now + 30);
(, uint256 _price, uint256 _lot,) = clip.getStatus(1);
- Guy(bob).take({
- id: 1,
- amt: _lot, // Buy the rest of the lot
+ Guy(bob)
+ .take({
+ id: 1,
+ amt: _lot, // Buy the rest of the lot
max: ray(_price), // 5 * 0.99 ** 30 = 3.698501866941401 RAY => max > price
who: address(bob),
data: ""
@@ -1131,24 +1071,24 @@ contract ClipperTest is DSTest {
assertEq(uint256(tic), 0);
assertEq(top, 0);
- uint256 expectedGem = (RAY * 60 ether) / _price; // tab / price
- assertEq(vat.gem(ilk, bob), expectedGem); // Didn't take whole lot
- assertEq(vat.dai(bob), rad(940 ether)); // Paid rest of tab (60)
+ uint256 expectedGem = (RAY * 60 ether) / _price; // tab / price
+ assertEq(vat.gem(ilk, bob), expectedGem); // Didn't take whole lot
+ assertEq(vat.dai(bob), rad(940 ether)); // Paid rest of tab (60)
- uint256 lotReturn = 30 ether - expectedGem; // lot - loaf.tab / max = 15
- assertEq(vat.gem(ilk, me), 960 ether + lotReturn); // Collateral returned (10 WAD)
+ uint256 lotReturn = 30 ether - expectedGem; // lot - loaf.tab / max = 15
+ assertEq(vat.gem(ilk, me), 960 ether + lotReturn); // Collateral returned (10 WAD)
}
function auctionResetSetup(uint256 tau) internal {
LinearDecrease calc = new LinearDecrease();
- calc.file(bytes32("tau"), tau); // tau hours till zero is reached (used to test tail)
+ calc.file(bytes32("tau"), tau); // tau hours till zero is reached (used to test tail)
vat.file(ilk, "dust", rad(20 ether)); // $20 dust
- clip.file("buf", ray(1.25 ether)); // 25% Initial price buffer
- clip.file("calc", address(calc)); // File price contract
- clip.file("cusp", ray(0.5 ether)); // 50% drop before reset
- clip.file("tail", 3600); // 1 hour before reset
+ clip.file("buf", ray(1.25 ether)); // 25% Initial price buffer
+ clip.file("calc", address(calc)); // File price contract
+ clip.file("cusp", ray(0.5 ether)); // 50% drop before reset
+ clip.file("tail", 3600); // 1 hour before reset
assertEq(clip.kicks(), 0);
dog.bark(ilk, me, address(this));
@@ -1179,7 +1119,7 @@ contract ClipperTest is DSTest {
assertTrue(try_redo(1, address(this)));
(,,,, uint96 ticAfter, uint256 topAfter) = clip.sales(1);
- assertEq(uint256(ticAfter), startTime + 3601 seconds); // (now)
+ assertEq(uint256(ticAfter), startTime + 3601 seconds); // (now)
assertEq(topAfter, ray(3.75 ether)); // $3 spot + 25% buffer = $5 (used most recent OSM price)
}
@@ -1202,7 +1142,7 @@ contract ClipperTest is DSTest {
assertTrue(try_redo(1, address(this)));
(,,,, uint96 ticAfter, uint256 topAfter) = clip.sales(1);
- assertEq(uint256(ticAfter), startTime + 1801 seconds); // (now)
+ assertEq(uint256(ticAfter), startTime + 1801 seconds); // (now)
assertEq(topAfter, ray(3.75 ether)); // $3 spot + 25% buffer = $3.75 (used most recent OSM price)
}
@@ -1245,7 +1185,7 @@ contract ClipperTest is DSTest {
uint256 tab;
uint256 lot;
address usr;
- uint96 tic;
+ uint96 tic;
uint256 top;
uint256 ink;
uint256 art;
@@ -1282,39 +1222,21 @@ contract ClipperTest is DSTest {
clip.file("stopped", 1);
// Bid so owe (= 25 * 5 = 125 RAD) > tab (= 110 RAD)
// Readjusts slice to be tab/top = 25
- Guy(ali).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(ali), data: ""});
}
function test_stopped_2_take() public takeSetup {
clip.file("stopped", 2);
// Bid so owe (= 25 * 5 = 125 RAD) > tab (= 110 RAD)
// Readjusts slice to be tab/top = 25
- Guy(ali).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(ali), data: ""});
}
function testFail_stopped_3_take() public takeSetup {
clip.file("stopped", 3);
// Bid so owe (= 25 * 5 = 125 RAD) > tab (= 110 RAD)
// Readjusts slice to be tab/top = 25
- Guy(ali).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(ali), data: ""});
}
function test_stopped_1_auction_reset_tail() public {
@@ -1334,7 +1256,7 @@ contract ClipperTest is DSTest {
assertTrue(try_redo(1, address(this)));
(,,,, uint96 ticAfter, uint256 topAfter) = clip.sales(1);
- assertEq(uint256(ticAfter), startTime + 3601 seconds); // (now)
+ assertEq(uint256(ticAfter), startTime + 3601 seconds); // (now)
assertEq(topAfter, ray(3.75 ether)); // $3 spot + 25% buffer = $5 (used most recent OSM price)
}
@@ -1351,8 +1273,8 @@ contract ClipperTest is DSTest {
hevm.warp(startTime + 3601 seconds);
(bool needsRedo,,,) = clip.getStatus(1);
- assertTrue(needsRedo); // Redo possible if circuit breaker not set
- assertTrue(!try_redo(1, address(this))); // Redo fails because of circuit breaker
+ assertTrue(needsRedo); // Redo possible if circuit breaker not set
+ assertTrue(!try_redo(1, address(this))); // Redo fails because of circuit breaker
}
function test_stopped_3_auction_reset_tail() public {
@@ -1368,13 +1290,13 @@ contract ClipperTest is DSTest {
hevm.warp(startTime + 3601 seconds);
(bool needsRedo,,,) = clip.getStatus(1);
- assertTrue(needsRedo); // Redo possible if circuit breaker not set
- assertTrue(!try_redo(1, address(this))); // Redo fails because of circuit breaker
+ assertTrue(needsRedo); // Redo possible if circuit breaker not set
+ assertTrue(!try_redo(1, address(this))); // Redo fails because of circuit breaker
}
function test_redo_incentive() public takeSetup {
- clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
- clip.file("chip", 0); // No linear increase
+ clip.file("tip", rad(100 ether)); // Flat fee of 100 DAI
+ clip.file("chip", 0); // No linear increase
(, uint256 tab, uint256 lot,,,) = clip.sales(1);
@@ -1385,7 +1307,7 @@ contract ClipperTest is DSTest {
clip.redo(1, address(123));
assertEq(vat.dai(address(123)), clip.tip());
- clip.file("chip", 0.02 ether); // Reward 2% of tab
+ clip.file("chip", 0.02 ether); // Reward 2% of tab
hevm.warp(now + 300);
clip.redo(1, address(234));
assertEq(vat.dai(address(234)), clip.tip() + clip.chip() * tab / WAD);
@@ -1413,13 +1335,7 @@ contract ClipperTest is DSTest {
(, uint256 price,,) = clip.getStatus(1);
assertEq(price, 1830161706366147524653080130); // 1.83 RAY
- clip.take({
- id: 1,
- amt: 38 ether,
- max: ray(5 ether),
- who: address(this),
- data: ""
- });
+ clip.take({id: 1, amt: 38 ether, max: ray(5 ether), who: address(this), data: ""});
(, tab, lot,,,) = clip.sales(1);
@@ -1451,9 +1367,9 @@ contract ClipperTest is DSTest {
uint256 preGemBalance = vat.gem(ilk, address(this));
(,, uint256 origLot,,,) = clip.sales(1);
- uint startGas = gasleft();
+ uint256 startGas = gasleft();
clip.yank(1);
- uint endGas = gasleft();
+ uint256 endGas = gasleft();
emit log_named_uint("yank gas", startGas - endGas);
// Assert that the auction was deleted.
@@ -1485,7 +1401,7 @@ contract ClipperTest is DSTest {
pclip.add();
// [1,2,3,4,5]
- assertEq(pclip.count(), 5); // 5 elements added
+ assertEq(pclip.count(), 5); // 5 elements added
assertEq(pclip.active(0), 1);
assertEq(pclip.active(1), 2);
assertEq(pclip.active(2), 3);
@@ -1498,7 +1414,7 @@ contract ClipperTest is DSTest {
assertEq(pclip.count(), 4);
assertEq(pclip.active(0), 1);
assertEq(pclip.active(1), 2);
- assertEq(pclip.active(2), 5); // Swapped last for middle
+ assertEq(pclip.active(2), 5); // Swapped last for middle
(pos,,,,,) = pclip.sales(5);
assertEq(pos, 2);
assertEq(pclip.active(3), 4);
@@ -1534,25 +1450,13 @@ contract ClipperTest is DSTest {
}
function testFail_not_enough_dai() public takeSetup {
- Guy(che).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(che),
- data: ""
- });
+ Guy(che).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(che), data: ""});
}
function test_flashsale() public takeSetup {
assertEq(vat.dai(che), 0);
assertEq(dai.balanceOf(che), 0);
- Guy(che).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(che),
- data: "hey"
- });
+ Guy(che).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(che), data: "hey"});
assertEq(vat.dai(che), 0);
assertTrue(dai.balanceOf(che) > 0); // Che turned a profit
}
@@ -1560,100 +1464,59 @@ contract ClipperTest is DSTest {
function testFail_reentrancy_take() public takeSetup {
BadGuy usr = new BadGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
function testFail_reentrancy_redo() public takeSetup {
RedoGuy usr = new RedoGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
function testFail_reentrancy_kick() public takeSetup {
KickGuy usr = new KickGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
clip.rely(address(usr));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
function testFail_reentrancy_file_uint() public takeSetup {
FileUintGuy usr = new FileUintGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
clip.rely(address(usr));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
function testFail_reentrancy_file_addr() public takeSetup {
FileAddrGuy usr = new FileAddrGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
clip.rely(address(usr));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
function testFail_reentrancy_yank() public takeSetup {
YankGuy usr = new YankGuy(clip);
usr.hope(address(clip));
- vat.suck(address(0), address(usr), rad(1000 ether));
+ vat.suck(address(0), address(usr), rad(1000 ether));
clip.rely(address(usr));
- usr.take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(usr),
- data: "hey"
- });
+ usr.take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(usr), data: "hey"});
}
- function testFail_take_impersonation() public takeSetup { // should fail, but works
+ function testFail_take_impersonation() public takeSetup {
+ // should fail, but works
Guy usr = new Guy(clip);
- usr.take({
- id: 1,
- amt: 99999999999999 ether,
- max: ray(99999999999999 ether),
- who: address(ali),
- data: ""
- });
+ usr.take({id: 1, amt: 99999999999999 ether, max: ray(99999999999999 ether), who: address(ali), data: ""});
}
function test_gas_bark_kick() public {
@@ -1681,9 +1544,10 @@ contract ClipperTest is DSTest {
function test_gas_partial_take() public takeSetup {
uint256 preGas = gasleft();
// Bid so owe (= 11 * 5 = 55 RAD) < tab (= 110 RAD)
- Guy(ali).take({
- id: 1,
- amt: 11 ether, // Half of tab at $110
+ Guy(ali)
+ .take({
+ id: 1,
+ amt: 11 ether, // Half of tab at $110
max: ray(5 ether),
who: address(ali),
data: ""
@@ -1691,15 +1555,15 @@ contract ClipperTest is DSTest {
uint256 diffGas = preGas - gasleft();
log_named_uint("partial take gas", diffGas);
- assertEq(vat.gem(ilk, ali), 11 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 11 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(945 ether)); // Paid half tab (55)
- assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
+ assertEq(vat.gem(ilk, me), 960 ether); // Collateral not returned (yet)
// Assert auction DOES NOT end
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
assertEq(pos, 0);
- assertEq(tab, rad(55 ether)); // 110 - 5 * 11
- assertEq(lot, 29 ether); // 40 - 11
+ assertEq(tab, rad(55 ether)); // 110 - 5 * 11
+ assertEq(lot, 29 ether); // 40 - 11
assertEq(usr, me);
assertEq(uint256(tic), now);
assertEq(top, ray(5 ether));
@@ -1709,19 +1573,13 @@ contract ClipperTest is DSTest {
uint256 preGas = gasleft();
// Bid so owe (= 25 * 5 = 125 RAD) > tab (= 110 RAD)
// Readjusts slice to be tab/top = 25
- Guy(ali).take({
- id: 1,
- amt: 25 ether,
- max: ray(5 ether),
- who: address(ali),
- data: ""
- });
+ Guy(ali).take({id: 1, amt: 25 ether, max: ray(5 ether), who: address(ali), data: ""});
uint256 diffGas = preGas - gasleft();
log_named_uint("full take gas", diffGas);
- assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
+ assertEq(vat.gem(ilk, ali), 22 ether); // Didn't take whole lot
assertEq(vat.dai(ali), rad(890 ether)); // Didn't pay more than tab (110)
- assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
+ assertEq(vat.gem(ilk, me), 978 ether); // 960 + (40 - 22) returned to usr
// Assert auction ends
(uint256 pos, uint256 tab, uint256 lot, address usr, uint256 tic, uint256 top) = clip.sales(1);
diff --git a/src/test/cure.t.sol b/src/test/cure.t.sol
index 17de561f..b0e91148 100644
--- a/src/test/cure.t.sol
+++ b/src/test/cure.t.sol
@@ -2,12 +2,12 @@
pragma solidity >=0.6.12;
-import { DSTest } from "ds-test/test.sol";
-import { Cure } from "../cure.sol";
+import {DSTest} from "ds-test/test.sol";
+import {Cure} from "../cure.sol";
interface Hevm {
function warp(uint256) external;
- function store(address,bytes32,bytes32) external;
+ function store(address, bytes32, bytes32) external;
}
contract SourceMock {
@@ -26,8 +26,7 @@ contract CureTest is DSTest {
Hevm hevm;
Cure cure;
- bytes20 constant CHEAT_CODE =
- bytes20(uint160(uint256(keccak256('hevm cheat code'))));
+ bytes20 constant CHEAT_CODE = bytes20(uint160(uint256(keccak256("hevm cheat code"))));
function setUp() public {
hevm = Hevm(address(CHEAT_CODE));
diff --git a/src/test/dai.t.sol b/src/test/dai.t.sol
index 60940c0a..ea10c3ab 100644
--- a/src/test/dai.t.sol
+++ b/src/test/dai.t.sol
@@ -17,93 +17,101 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-pragma solidity ^0.6.12;
+pragma solidity ^0.8.0;
+
+/**
+ * @title DAITest
+ * @dev Test contract for the DAI token
+ * @dev Implemented vm.expectRevert() into Revert test functions via the standard Vm interface address
+ */
import "ds-test/test.sol";
import "../dai.sol";
contract TokenUser {
- Dai token;
+ Dai token;
+
+ uint256 internal constant MAX_UINT = type(uint256).max;
- constructor(Dai token_) public {
+ constructor(Dai token_) {
token = token_;
}
- function doTransferFrom(address from, address to, uint amount)
- public
- returns (bool)
- {
+ function doTransferFrom(address from, address to, uint256 amount) public returns (bool) {
return token.transferFrom(from, to, amount);
}
- function doTransfer(address to, uint amount)
- public
- returns (bool)
- {
+ function doTransfer(address to, uint256 amount) public returns (bool) {
return token.transfer(to, amount);
}
- function doApprove(address recipient, uint amount)
- public
- returns (bool)
- {
+ function doApprove(address recipient, uint256 amount) public returns (bool) {
return token.approve(recipient, amount);
}
- function doAllowance(address owner, address spender)
- public
- view
- returns (uint)
- {
+ function doAllowance(address owner, address spender) public view returns (uint256) {
return token.allowance(owner, spender);
}
- function doBalanceOf(address who) public view returns (uint) {
+ function doBalanceOf(address who) public view returns (uint256) {
return token.balanceOf(who);
}
- function doApprove(address guy)
- public
- returns (bool)
- {
- return token.approve(guy, uint(-1));
+ function doApprove(address guy) public returns (bool) {
+ return token.approve(guy, MAX_UINT);
}
- function doMint(uint wad) public {
+
+ function doMint(uint256 wad) public {
token.mint(address(this), wad);
}
- function doBurn(uint wad) public {
+
+ function doBurn(uint256 wad) public {
token.burn(address(this), wad);
}
- function doMint(address guy, uint wad) public {
+
+ function doMint(address guy, uint256 wad) public {
token.mint(guy, wad);
}
- function doBurn(address guy, uint wad) public {
+
+ function doBurn(address guy, uint256 wad) public {
token.burn(guy, wad);
}
-
}
+/*//////////////////////////////////////////////////////////////
+ INTERFACE
+//////////////////////////////////////////////////////////////*/
interface Hevm {
function warp(uint256) external;
}
+interface Vm {
+ function expectRevert() external;
+ function addr(uint256 privateKey) external returns (address);
+ function sign(uint256 privateKey, bytes32 digest) external returns (uint8, bytes32, bytes32);
+}
+
contract DaiTest is DSTest {
- uint constant initialBalanceThis = 1000;
- uint constant initialBalanceCal = 100;
+ uint256 constant initialBalanceThis = 1000;
+ uint256 constant initialBalanceCal = 100;
+ uint256 constant calKey = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; // any nonzero test key
+ uint256 internal constant MAX_UINT = type(uint256).max;
+ uint256 constant delKey = 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d;
+ address cal;
+ address del;
Dai token;
Hevm hevm;
+ Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
address user1;
address user2;
address self;
- uint amount = 2;
- uint fee = 1;
- uint nonce = 0;
- uint deadline = 0;
- address cal = 0x29C76e6aD8f28BB1004902578Fb108c507Be341b;
- address del = 0xdd2d5D3f7f1b35b7A0601D6A00DbB7D44Af58479;
+ uint256 amount = 2;
+ uint256 fee = 1;
+ uint256 nonce = 0;
+ uint256 deadline = 0;
bytes32 r = 0x8e30095d9e5439a4f4b8e4b5c94e7639756474d72aded20611464c8f002efb06;
bytes32 s = 0x49a0ed09658bc768d6548689bcbaa430cefa57846ef83cb685673a9b9a575ff4;
uint8 v = 27;
@@ -111,10 +119,11 @@ contract DaiTest is DSTest {
bytes32 _s = 0x7e8e641e5e8bef932c3a55e7365e0201196fc6385d942c47d749bf76e73ee46f;
uint8 _v = 27;
-
function setUp() public {
- hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
+ hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); ///////
hevm.warp(604411200);
+ cal = vm.addr(calKey);
+ del = vm.addr(delKey);
token = createToken();
token.mint(address(this), initialBalanceThis);
token.mint(cal, initialBalanceCal);
@@ -132,7 +141,7 @@ contract DaiTest is DSTest {
}
function testTransferCost() public logs_gas {
- token.transfer(address(0), 10);
+ assertTrue(token.transfer(address(0), 10));
}
function testAllowanceStartsAtZero() public logs_gas {
@@ -140,22 +149,24 @@ contract DaiTest is DSTest {
}
function testValidTransfers() public logs_gas {
- uint sentAmount = 250;
+ uint256 sentAmount = 250;
emit log_named_address("token11111", address(token));
- token.transfer(user2, sentAmount);
+ assertTrue(token.transfer(user2, sentAmount));
assertEq(token.balanceOf(user2), sentAmount);
assertEq(token.balanceOf(self), initialBalanceThis - sentAmount);
}
- function testFailWrongAccountTransfers() public logs_gas {
- uint sentAmount = 250;
- token.transferFrom(user2, self, sentAmount);
+ function testRevertIfWrongAccountTransfers() public logs_gas {
+ uint256 sentAmount = 250;
+ vm.expectRevert();
+ assertTrue(token.transferFrom(user2, self, sentAmount));
}
- function testFailInsufficientFundsTransfers() public logs_gas {
- uint sentAmount = 250;
- token.transfer(user1, initialBalanceThis - sentAmount);
- token.transfer(user2, sentAmount + 1);
+ function testRevertInsufficientFundsTransfers() public logs_gas {
+ uint256 sentAmount = 250;
+ assertTrue(token.transfer(user1, initialBalanceThis - sentAmount));
+ vm.expectRevert();
+ assertTrue(token.transfer(user2, sentAmount + 1));
}
function testApproveSetsAllowance() public logs_gas {
@@ -168,96 +179,114 @@ contract DaiTest is DSTest {
}
function testChargesAmountApproved() public logs_gas {
- uint amountApproved = 20;
+ uint256 amountApproved = 20;
token.approve(user2, amountApproved);
assertTrue(TokenUser(user2).doTransferFrom(self, user2, amountApproved));
assertEq(token.balanceOf(self), initialBalanceThis - amountApproved);
}
- function testFailTransferWithoutApproval() public logs_gas {
- token.transfer(user1, 50);
- token.transferFrom(user1, self, 1);
+ function testRevertTransferWithoutApproval() public logs_gas {
+ assertTrue(token.transfer(user1, 50));
+ vm.expectRevert();
+ assertTrue(token.transferFrom(user1, self, 1));
}
- function testFailChargeMoreThanApproved() public logs_gas {
- token.transfer(user1, 50);
+ function testRevertChargeMoreThanApproved() public logs_gas {
+ assertTrue(token.transfer(user1, 50));
TokenUser(user1).doApprove(self, 20);
- token.transferFrom(user1, self, 21);
+ vm.expectRevert();
+ assertTrue(token.transferFrom(user1, self, 21));
}
+
function testTransferFromSelf() public {
- token.transferFrom(self, user1, 50);
+ assertTrue(token.transferFrom(self, user1, 50));
assertEq(token.balanceOf(user1), 50);
}
- function testFailTransferFromSelfNonArbitrarySize() public {
- // you shouldn't be able to evade balance checks by transferring
- // to yourself
- token.transferFrom(self, self, token.balanceOf(self) + 1);
+
+ function testRevertTransferFromSelfNonArbitrarySize() public {
+ uint256 _amount = token.balanceOf(self) + 1;
+
+ vm.expectRevert();
+ assertTrue(token.transferFrom(self, self, _amount));
}
+
function testMintself() public {
- uint mintAmount = 10;
+ uint256 mintAmount = 10;
token.mint(address(this), mintAmount);
assertEq(token.balanceOf(self), initialBalanceThis + mintAmount);
}
+
function testMintGuy() public {
- uint mintAmount = 10;
+ uint256 mintAmount = 10;
token.mint(user1, mintAmount);
assertEq(token.balanceOf(user1), mintAmount);
}
- function testFailMintGuyNoAuth() public {
+
+ function testRevertMintGuyNoAuth() public {
+ vm.expectRevert();
TokenUser(user1).doMint(user2, 10);
}
+
function testMintGuyAuth() public {
token.rely(user1);
TokenUser(user1).doMint(user2, 10);
}
function testBurn() public {
- uint burnAmount = 10;
+ uint256 burnAmount = 10;
token.burn(address(this), burnAmount);
assertEq(token.totalSupply(), initialBalanceThis + initialBalanceCal - burnAmount);
}
+
function testBurnself() public {
- uint burnAmount = 10;
+ uint256 burnAmount = 10;
token.burn(address(this), burnAmount);
assertEq(token.balanceOf(self), initialBalanceThis - burnAmount);
}
+
function testBurnGuyWithTrust() public {
- uint burnAmount = 10;
- token.transfer(user1, burnAmount);
+ uint256 burnAmount = 10;
+ assertTrue(token.transfer(user1, burnAmount));
assertEq(token.balanceOf(user1), burnAmount);
TokenUser(user1).doApprove(self);
token.burn(user1, burnAmount);
assertEq(token.balanceOf(user1), 0);
}
+
function testBurnAuth() public {
- token.transfer(user1, 10);
+ assertTrue(token.transfer(user1, 10));
token.rely(user1);
TokenUser(user1).doBurn(10);
}
+
function testBurnGuyAuth() public {
- token.transfer(user2, 10);
+ assertTrue(token.transfer(user2, 10));
// token.rely(user1);
TokenUser(user2).doApprove(user1);
TokenUser(user1).doBurn(user2, 10);
}
- function testFailUntrustedTransferFrom() public {
+ function testRevertUntrustedTransferFrom() public {
assertEq(token.allowance(self, user2), 0);
+ vm.expectRevert();
TokenUser(user1).doTransferFrom(self, user2, 200);
}
+
function testTrusting() public {
assertEq(token.allowance(self, user2), 0);
- token.approve(user2, uint(-1));
- assertEq(token.allowance(self, user2), uint(-1));
+ token.approve(user2, MAX_UINT);
+ assertEq(token.allowance(self, user2), MAX_UINT);
token.approve(user2, 0);
assertEq(token.allowance(self, user2), 0);
}
+
function testTrustedTransferFrom() public {
- token.approve(user1, uint(-1));
+ token.approve(user1, MAX_UINT);
TokenUser(user1).doTransferFrom(self, user2, 200);
assertEq(token.balanceOf(user2), 200);
}
+
function testApproveWillModifyAllowance() public {
assertEq(token.allowance(self, user1), 0);
assertEq(token.balanceOf(user1), 0);
@@ -267,15 +296,17 @@ contract DaiTest is DSTest {
assertEq(token.balanceOf(user1), 500);
assertEq(token.allowance(self, user1), 500);
}
+
function testApproveWillNotModifyAllowance() public {
assertEq(token.allowance(self, user1), 0);
assertEq(token.balanceOf(user1), 0);
- token.approve(user1, uint(-1));
- assertEq(token.allowance(self, user1), uint(-1));
+ token.approve(user1, MAX_UINT);
+ assertEq(token.allowance(self, user1), MAX_UINT);
TokenUser(user1).doTransferFrom(self, user1, 1000);
assertEq(token.balanceOf(user1), 1000);
- assertEq(token.allowance(self, user1), uint(-1));
+ assertEq(token.allowance(self, user1), MAX_UINT);
}
+
function testDaiAddress() public {
//The dai address generated by hevm
//used for signature generation testing
@@ -293,31 +324,72 @@ contract DaiTest is DSTest {
function testPermit() public {
assertEq(token.nonces(cal), 0);
assertEq(token.allowance(cal, del), 0);
- token.permit(cal, del, 0, 0, true, v, r, s);
- assertEq(token.allowance(cal, del),uint(-1));
- assertEq(token.nonces(cal),1);
+
+ bytes32 digest = keccak256(
+ abi.encodePacked(
+ "\x19\x01",
+ token.DOMAIN_SEPARATOR(),
+ keccak256(abi.encode(token.PERMIT_TYPEHASH(), cal, del, 0, 0, true))
+ )
+ );
+
+ (uint8 sigV, bytes32 sigR, bytes32 sigS) = vm.sign(calKey, digest);
+ token.permit(cal, del, 0, 0, true, sigV, sigR, sigS);
+
+ assertEq(token.allowance(cal, del), MAX_UINT);
+ assertEq(token.nonces(cal), 1);
}
- function testFailPermitAddress0() public {
+ function testRevertPermitAddress0() public {
v = 0;
+ vm.expectRevert();
token.permit(address(0), del, 0, 0, true, v, r, s);
}
function testPermitWithExpiry() public {
- assertEq(now, 604411200);
- token.permit(cal, del, 0, 604411200 + 1 hours, true, _v, _r, _s);
- assertEq(token.allowance(cal, del),uint(-1));
- assertEq(token.nonces(cal),1);
+ assertEq(block.timestamp, 604411200);
+
+ uint256 expiry = block.timestamp + 1 hours;
+
+ bytes32 digest = keccak256(
+ abi.encodePacked(
+ "\x19\x01",
+ token.DOMAIN_SEPARATOR(),
+ keccak256(abi.encode(token.PERMIT_TYPEHASH(), cal, del, 0, expiry, true))
+ )
+ );
+
+ (uint8 sigV, bytes32 sigR, bytes32 sigS) = vm.sign(calKey, digest);
+
+ token.permit(cal, del, 0, expiry, true, sigV, sigR, sigS);
+
+ assertEq(token.allowance(cal, del), MAX_UINT);
+ assertEq(token.nonces(cal), 1);
}
- function testFailPermitWithExpiry() public {
- hevm.warp(now + 2 hours);
- assertEq(now, 604411200 + 2 hours);
+ function testRevertPermitWithExpiry() public {
+ hevm.warp(block.timestamp + 2 hours);
+ assertEq(block.timestamp, 604411200 + 2 hours);
+ vm.expectRevert();
token.permit(cal, del, 0, 1, true, _v, _r, _s);
}
- function testFailReplay() public {
- token.permit(cal, del, 0, 0, true, v, r, s);
- token.permit(cal, del, 0, 0, true, v, r, s);
+ function testRevertReplay() public {
+ bytes32 digest = keccak256(
+ abi.encodePacked(
+ "\x19\x01",
+ token.DOMAIN_SEPARATOR(),
+ keccak256(abi.encode(token.PERMIT_TYPEHASH(), cal, del, 0, 0, true))
+ )
+ );
+
+ (uint8 sigV, bytes32 sigR, bytes32 sigS) = vm.sign(calKey, digest);
+
+ // First permit should succeed
+ token.permit(cal, del, 0, 0, true, sigV, sigR, sigS);
+
+ // Second permit with same signature should revert (nonce has incremented)
+ vm.expectRevert();
+ token.permit(cal, del, 0, 0, true, sigV, sigR, sigS);
}
}
diff --git a/src/test/dog.t.sol b/src/test/dog.t.sol
index eeaf939f..87246ec1 100644
--- a/src/test/dog.t.sol
+++ b/src/test/dog.t.sol
@@ -19,33 +19,33 @@
pragma solidity ^0.6.12;
-import { DSTest } from "ds-test/test.sol";
-import { Vat } from "../vat.sol";
-import { Dog } from "../dog.sol";
+import {DSTest} from "ds-test/test.sol";
+import {Vat} from "../vat.sol";
+import {Dog} from "../dog.sol";
contract VowMock {
- function fess (uint256 due) public {}
+ function fess(uint256 due) public {}
}
contract ClipperMock {
bytes32 public ilk;
+
function setIlk(bytes32 wat) external {
ilk = wat;
}
- function kick(uint256, uint256, address, address)
- external pure returns (uint256 id) {
+
+ function kick(uint256, uint256, address, address) external pure returns (uint256 id) {
id = 42;
}
}
contract DogTest is DSTest {
-
bytes32 constant ilk = "gold";
address constant usr = address(1337);
- uint256 constant THOUSAND = 1E3;
- uint256 constant WAD = 1E18;
- uint256 constant RAY = 1E27;
- uint256 constant RAD = 1E45;
+ uint256 constant THOUSAND = 1e3;
+ uint256 constant WAD = 1e18;
+ uint256 constant RAY = 1e27;
+ uint256 constant RAD = 1e45;
Vat vat;
VowMock vow;
ClipperMock clip;
@@ -203,13 +203,13 @@ contract DogTest is DSTest {
// was also dusty and would fit in the remaining hole/Hole room.
function test_bark_dusty_vault_dusty_room() public {
// Use a chop that will give nice round numbers
- uint256 CHOP = 110 * WAD / 100; // 10%
+ uint256 CHOP = 110 * WAD / 100; // 10%
dog.file(ilk, "chop", CHOP);
// set both hole_i and Hole to the same value for this test
uint256 ROOM = 200;
uint256 HOLE = 33 * THOUSAND + ROOM;
- dog.file( "Hole", HOLE * RAD);
+ dog.file("Hole", HOLE * RAD);
dog.file(ilk, "hole", HOLE * RAD);
// Test using a non-zero rate to ensure the code is handling stability fees correctly.
@@ -227,7 +227,7 @@ contract DogTest is DSTest {
// Create a small vault
uint256 DUST_1 = 30;
vat.file(ilk, "dust", DUST_1 * RAD);
- setUrn(WAD / 10**4, DUST_1 * RAD / rate);
+ setUrn(WAD / 10 ** 4, DUST_1 * RAD / rate);
// Dust limit goes up!
uint256 DUST_2 = 1500;
@@ -277,7 +277,7 @@ contract DogTest is DSTest {
// This will need to be partially liquidated
setUrn(WAD, hole * WAD * WAD / chop);
- assertTrue(!try_bark(ilk, usr, address(this))); // should revert, as the auction would be dusty
+ assertTrue(!try_bark(ilk, usr, address(this))); // should revert, as the auction would be dusty
}
function test_bark_do_not_create_dusty_auction_Hole() public {
@@ -302,6 +302,6 @@ contract DogTest is DSTest {
// This will need to be partially liquidated
setUrn(WAD, Hole * WAD * WAD / chop);
- assertTrue(!try_bark(ilk, usr, address(this))); // should revert, as the auction would be dusty
+ assertTrue(!try_bark(ilk, usr, address(this))); // should revert, as the auction would be dusty
}
}
diff --git a/src/test/end.t.sol b/src/test/end.t.sol
index f6b99bd8..a67d3ccb 100644
--- a/src/test/end.t.sol
+++ b/src/test/end.t.sol
@@ -24,19 +24,19 @@ import "ds-test/test.sol";
import "ds-token/token.sol";
import "ds-value/value.sol";
-import {Vat} from '../vat.sol';
-import {Cat} from '../cat.sol';
-import {Dog} from '../dog.sol';
-import {Vow} from '../vow.sol';
-import {Pot} from '../pot.sol';
-import {Flipper} from '../flip.sol';
-import {Clipper} from '../clip.sol';
-import {Flapper} from '../flap.sol';
-import {Flopper} from '../flop.sol';
-import {GemJoin} from '../join.sol';
-import {End} from '../end.sol';
-import {Spotter} from '../spot.sol';
-import {Cure} from '../cure.sol';
+import {Vat} from "../vat.sol";
+import {Cat} from "../cat.sol";
+import {Dog} from "../dog.sol";
+import {Vow} from "../vow.sol";
+import {Pot} from "../pot.sol";
+import {Flipper} from "../flip.sol";
+import {Clipper} from "../clip.sol";
+import {Flapper} from "../flap.sol";
+import {Flopper} from "../flop.sol";
+import {GemJoin} from "../join.sol";
+import {End} from "../end.sol";
+import {Spotter} from "../spot.sol";
+import {Cure} from "../cure.sol";
interface Hevm {
function warp(uint256) external;
@@ -47,31 +47,39 @@ contract Usr {
End public end;
constructor(Vat vat_, End end_) public {
- vat = vat_;
- end = end_;
+ vat = vat_;
+ end = end_;
}
- function frob(bytes32 ilk, address u, address v, address w, int dink, int dart) public {
+
+ function frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) public {
vat.frob(ilk, u, v, w, dink, dart);
}
+
function flux(bytes32 ilk, address src, address dst, uint256 wad) public {
vat.flux(ilk, src, dst, wad);
}
+
function move(address src, address dst, uint256 rad) public {
vat.move(src, dst, rad);
}
+
function hope(address usr) public {
vat.hope(usr);
}
- function exit(GemJoin gemA, address usr, uint wad) public {
+
+ function exit(GemJoin gemA, address usr, uint256 wad) public {
gemA.exit(usr, wad);
}
+
function free(bytes32 ilk) public {
end.free(ilk);
}
+
function pack(uint256 rad) public {
end.pack(rad);
}
- function cash(bytes32 ilk, uint wad) public {
+
+ function cash(bytes32 ilk, uint256 wad) public {
end.cash(ilk, wad);
}
}
@@ -79,12 +87,12 @@ contract Usr {
contract EndTest is DSTest {
Hevm hevm;
- Vat vat;
- End end;
- Vow vow;
- Pot pot;
- Cat cat;
- Dog dog;
+ Vat vat;
+ End end;
+ Vow vow;
+ Pot pot;
+ Cat cat;
+ Dog dog;
Spotter spot;
@@ -98,53 +106,67 @@ contract EndTest is DSTest {
Clipper clip;
}
- mapping (bytes32 => Ilk) ilks;
+ mapping(bytes32 => Ilk) ilks;
Flapper flap;
Flopper flop;
- uint constant WAD = 10 ** 18;
- uint constant RAY = 10 ** 27;
- uint constant MLN = 10 ** 6;
+ uint256 constant WAD = 10 ** 18;
+ uint256 constant RAY = 10 ** 27;
+ uint256 constant MLN = 10 ** 6;
- function ray(uint wad) internal pure returns (uint) {
+ function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * RAY;
}
- function rmul(uint x, uint y) internal pure returns (uint z) {
+
+ function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x * y;
require(y == 0 || z / y == x);
z = z / RAY;
}
- function min(uint x, uint y) internal pure returns (uint z) {
+
+ function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
(x >= y) ? z = y : z = x;
}
- function dai(address urn) internal view returns (uint) {
+
+ function dai(address urn) internal view returns (uint256) {
return vat.dai(urn) / RAY;
}
- function gem(bytes32 ilk, address urn) internal view returns (uint) {
+
+ function gem(bytes32 ilk, address urn) internal view returns (uint256) {
return vat.gem(ilk, urn);
}
- function ink(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); art_;
+
+ function ink(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ art_;
return ink_;
}
- function art(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); ink_;
+
+ function art(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ ink_;
return art_;
}
- function Art(bytes32 ilk) internal view returns (uint) {
- (uint Art_, uint rate_, uint spot_, uint line_, uint dust_) = vat.ilks(ilk);
- rate_; spot_; line_; dust_;
+
+ function Art(bytes32 ilk) internal view returns (uint256) {
+ (uint256 Art_, uint256 rate_, uint256 spot_, uint256 line_, uint256 dust_) = vat.ilks(ilk);
+ rate_;
+ spot_;
+ line_;
+ dust_;
return Art_;
}
- function balanceOf(bytes32 ilk, address usr) internal view returns (uint) {
+
+ function balanceOf(bytes32 ilk, address usr) internal view returns (uint256) {
return ilks[ilk].gem.balanceOf(usr);
}
- function try_pot_file(bytes32 what, uint data) public returns(bool ok) {
+ function try_pot_file(bytes32 what, uint256 data) public returns (bool ok) {
string memory sig = "file(bytes32, uint)";
(ok,) = address(pot).call(abi.encodeWithSignature(sig, what, data));
}
@@ -205,7 +227,7 @@ contract EndTest is DSTest {
hevm.warp(604411200);
vat = new Vat();
- DSToken gov = new DSToken('GOV');
+ DSToken gov = new DSToken("GOV");
flap = new Flapper(address(vat), address(gov));
flop = new Flopper(address(vat), address(gov));
@@ -228,7 +250,7 @@ contract EndTest is DSTest {
vow.rely(address(dog));
spot = new Spotter(address(vat));
- vat.file("Line", rad(1_000_000 ether));
+ vat.file("Line", rad(1_000_000 ether));
vat.rely(address(spot));
cure = new Cure();
@@ -372,8 +394,8 @@ contract EndTest is DSTest {
gold.pip.poke(bytes32(2 * WAD));
end.cage();
end.cage("gold");
- end.skim("gold", urn1); // over-collateralised
- end.skim("gold", urn2); // under-collateralised
+ end.skim("gold", urn1); // over-collateralised
+ end.skim("gold", urn2); // under-collateralised
// local checks
assertEq(art("gold", urn1), 0);
@@ -448,14 +470,14 @@ contract EndTest is DSTest {
ali.frob("gold", urn1, urn1, urn1, 10 ether, 15 ether);
// this urn has 0 gem, 10 ink, 15 tab, 15 dai
- vat.file("gold", "spot", ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
- uint auction = cat.bite("gold", urn1); // CDP liquidated
- assertEq(vat.vice(), rad(15 ether)); // now there is sin
+ uint256 auction = cat.bite("gold", urn1); // CDP liquidated
+ assertEq(vat.vice(), rad(15 ether)); // now there is sin
// get 1 dai from ali
ali.move(address(ali), address(this), rad(1 ether));
vat.hope(address(gold.flip));
- (,uint lot,,,,,,) = gold.flip.bids(auction);
+ (, uint256 lot,,,,,,) = gold.flip.bids(auction);
gold.flip.tend(auction, lot, rad(1 ether)); // bid 1 dai
assertEq(dai(urn1), 14 ether);
@@ -465,7 +487,7 @@ contract EndTest is DSTest {
end.cage("gold");
end.skip("gold", auction);
- assertEq(dai(address(this)), 1 ether); // bid refunded
+ assertEq(dai(address(this)), 1 ether); // bid refunded
vat.move(address(this), urn1, rad(1 ether)); // return 1 dai to ali
end.skim("gold", urn1);
@@ -525,8 +547,8 @@ contract EndTest is DSTest {
address urn1 = address(ali);
gold.gemA.join(urn1, 10 ether);
ali.frob("gold", urn1, urn1, urn1, 10 ether, 15 ether);
- (uint ink1, uint art1) = vat.urns("gold", urn1); // CDP before liquidation
- (, uint rate,,,) = vat.ilks("gold");
+ (uint256 ink1, uint256 art1) = vat.urns("gold", urn1); // CDP before liquidation
+ (, uint256 rate,,,) = vat.ilks("gold");
assertEq(vat.gem("gold", urn1), 0);
assertEq(rate, ray(1.25 ether));
@@ -542,7 +564,7 @@ contract EndTest is DSTest {
{
uint256 pos1;
address usr1;
- uint96 tic1;
+ uint96 tic1;
uint256 top1;
(pos1, tab1, lot1, usr1, tic1, top1) = gold.clip.sales(id);
assertEq(pos1, 0);
@@ -556,7 +578,7 @@ contract EndTest is DSTest {
assertEq(dog.Dirt(), tab1);
{
- (uint ink2, uint art2) = vat.urns("gold", urn1); // CDP after liquidation
+ (uint256 ink2, uint256 art2) = vat.urns("gold", urn1); // CDP after liquidation
assertEq(ink2, 0);
assertEq(art2, 0);
}
@@ -569,10 +591,10 @@ contract EndTest is DSTest {
assertEq(end.tag("gold"), ray(0.2 ether)); // par / price = collateral per DAI
assertEq(vat.gem("gold", address(gold.clip)), lot1); // From grab in dog.bark()
- assertEq(vat.sin(address(vow)), art1 * rate); // From grab in dog.bark()
- assertEq(vat.vice(), art1 * rate); // From grab in dog.bark()
- assertEq(vat.debt(), art1 * rate); // From frob
- assertEq(vat.dai(address(vow)), 0); // vat.suck() hasn't been called
+ assertEq(vat.sin(address(vow)), art1 * rate); // From grab in dog.bark()
+ assertEq(vat.vice(), art1 * rate); // From grab in dog.bark()
+ assertEq(vat.debt(), art1 * rate); // From frob
+ assertEq(vat.dai(address(vow)), 0); // vat.suck() hasn't been called
end.snip("gold", id);
@@ -581,29 +603,29 @@ contract EndTest is DSTest {
uint256 tab2;
uint256 lot2;
address usr2;
- uint96 tic2;
+ uint96 tic2;
uint256 top2;
(pos2, tab2, lot2, usr2, tic2, top2) = gold.clip.sales(id);
- assertEq(pos2, 0);
- assertEq(tab2, 0);
- assertEq(lot2, 0);
- assertEq(usr2, address(0));
+ assertEq(pos2, 0);
+ assertEq(tab2, 0);
+ assertEq(lot2, 0);
+ assertEq(usr2, address(0));
assertEq(uint256(tic2), 0);
assertEq(uint256(top2), 0);
}
- assertEq(dog.Dirt(), 0); // From clip.yank()
- assertEq(vat.gem("gold", address(gold.clip)), 0); // From clip.yank()
- assertEq(vat.gem("gold", address(end)), 0); // From grab in end.snip()
- assertEq(vat.sin(address(vow)), art1 * rate); // From grab in dog.bark()
- assertEq(vat.vice(), art1 * rate); // From grab in dog.bark()
- assertEq(vat.debt(), tab1 + art1 * rate); // From frob and suck
- assertEq(vat.dai(address(vow)), tab1); // From vat.suck()
- assertEq(end.Art("gold") * rate, tab1); // Incrementing total Art in End
+ assertEq(dog.Dirt(), 0); // From clip.yank()
+ assertEq(vat.gem("gold", address(gold.clip)), 0); // From clip.yank()
+ assertEq(vat.gem("gold", address(end)), 0); // From grab in end.snip()
+ assertEq(vat.sin(address(vow)), art1 * rate); // From grab in dog.bark()
+ assertEq(vat.vice(), art1 * rate); // From grab in dog.bark()
+ assertEq(vat.debt(), tab1 + art1 * rate); // From frob and suck
+ assertEq(vat.dai(address(vow)), tab1); // From vat.suck()
+ assertEq(end.Art("gold") * rate, tab1); // Incrementing total Art in End
- (uint ink3, uint art3) = vat.urns("gold", urn1); // CDP after snip
- assertEq(ink3, 10 ether); // All collateral returned to CDP
- assertEq(art3, tab1 / rate); // Tab amount of normalized debt transferred back into CDP
+ (uint256 ink3, uint256 art3) = vat.urns("gold", urn1); // CDP after snip
+ assertEq(ink3, 10 ether); // All collateral returned to CDP
+ assertEq(art3, tab1 / rate); // Tab amount of normalized debt transferred back into CDP
}
// -- Scenario where there is one over-collateralised CDP
@@ -702,8 +724,8 @@ contract EndTest is DSTest {
gold.pip.poke(bytes32(2 * WAD));
end.cage();
end.cage("gold");
- end.skim("gold", urn1); // over-collateralised
- end.skim("gold", urn2); // under-collateralised
+ end.skim("gold", urn1); // over-collateralised
+ end.skim("gold", urn2); // under-collateralised
// local checks
assertEq(art("gold", urn1), 0);
@@ -797,8 +819,8 @@ contract EndTest is DSTest {
end.cage();
end.cage("gold");
end.cage("coal");
- end.skim("gold", urn1); // over-collateralised
- end.skim("coal", urn2); // under-collateralised
+ end.skim("gold", urn1); // over-collateralised
+ end.skim("coal", urn2); // under-collateralised
hevm.warp(now + 1 hours);
end.thaw();
@@ -808,15 +830,15 @@ contract EndTest is DSTest {
ali.hope(address(end));
bob.hope(address(end));
- assertEq(vat.debt(), rad(20 ether));
- assertEq(vat.vice(), rad(20 ether));
- assertEq(vat.sin(address(vow)), rad(20 ether));
+ assertEq(vat.debt(), rad(20 ether));
+ assertEq(vat.vice(), rad(20 ether));
+ assertEq(vat.sin(address(vow)), rad(20 ether));
assertEq(end.Art("gold"), 15 ether);
- assertEq(end.Art("coal"), 5 ether);
+ assertEq(end.Art("coal"), 5 ether);
- assertEq(end.gap("gold"), 0.0 ether);
- assertEq(end.gap("coal"), 1.5 ether);
+ assertEq(end.gap("gold"), 0.0 ether);
+ assertEq(end.gap("coal"), 1.5 ether);
// there are 7.5 gold and 1 coal
// the gold is worth 15 dai and the coal is worth 2 dai
@@ -824,7 +846,7 @@ contract EndTest is DSTest {
// the total outstanding debt is 20 dai
// each dai should get (15/2)/20 gold and (2/2)/20 coal
assertEq(end.fix("gold"), ray(0.375 ether));
- assertEq(end.fix("coal"), ray(0.050 ether));
+ assertEq(end.fix("coal"), ray(0.05 ether));
assertEq(gem("gold", address(ali)), 0 ether);
ali.pack(1 ether);
@@ -836,7 +858,7 @@ contract EndTest is DSTest {
assertEq(gem("coal", address(bob)), 0.05 ether);
ali.exit(gold.gemA, address(ali), 0.375 ether);
- bob.exit(coal.gemA, address(bob), 0.05 ether);
+ bob.exit(coal.gemA, address(bob), 0.05 ether);
ali.pack(1 ether);
ali.cash("gold", 1 ether);
ali.cash("coal", 1 ether);
@@ -844,7 +866,7 @@ contract EndTest is DSTest {
assertEq(gem("coal", address(ali)), 0.05 ether);
ali.exit(gold.gemA, address(ali), 0.375 ether);
- ali.exit(coal.gemA, address(ali), 0.05 ether);
+ ali.exit(coal.gemA, address(ali), 0.05 ether);
ali.pack(1 ether);
ali.cash("gold", 1 ether);
@@ -900,40 +922,48 @@ contract EndTest is DSTest {
end.flow("gold");
}
- uint256 constant RAD = 10**45;
+ uint256 constant RAD = 10 ** 45;
+
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
+
function wdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, WAD) / y;
}
+
function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, RAY) / y;
}
+
function fix_calc_0(uint256 col, uint256 debt) internal pure returns (uint256) {
return rdiv(mul(col, RAY), debt);
}
+
function fix_calc_1(uint256 col, uint256 debt) internal pure returns (uint256) {
- return wdiv(mul(col, RAY), (debt / 10**9));
+ return wdiv(mul(col, RAY), (debt / 10 ** 9));
}
+
function fix_calc_2(uint256 col, uint256 debt) internal pure returns (uint256) {
return mul(col, RAY) / (debt / RAY);
}
+
function wAssertCloseEnough(uint256 x, uint256 y) internal {
uint256 diff = x > y ? x - y : y - x;
if (diff == 0) return;
uint256 xErr = mul(diff, WAD) / x;
uint256 yErr = mul(diff, WAD) / y;
- uint256 err = xErr > yErr ? xErr : yErr;
- assertTrue(err < WAD / 100_000_000); // Error no more than one part in a hundred million
+ uint256 err = xErr > yErr ? xErr : yErr;
+ assertTrue(err < WAD / 100_000_000); // Error no more than one part in a hundred million
}
- uint256 constant MIN_DEBT = 10**6 * RAD; // Minimum debt for fuzz runs
- uint256 constant REDEEM_AMT = 1_000 * WAD; // Amount of DAI to redeem for error checking
+ uint256 constant MIN_DEBT = 10 ** 6 * RAD; // Minimum debt for fuzz runs
+ uint256 constant REDEEM_AMT = 1_000 * WAD; // Amount of DAI to redeem for error checking
+
function test_fuzz_fix_calcs_0_1(uint256 col_seed, uint192 debt_seed) public {
- uint256 col = col_seed % (115792 * WAD); // somewhat biased, but not enough to matter
- if (col < 10**12) col += 10**12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
+ uint256 col = col_seed % (115792 * WAD); // somewhat biased, but not enough to matter
+ if (col < 10 ** 12) col += 10 ** 12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
uint256 debt = debt_seed;
- if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
+ if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
uint256 fix0 = fix_calc_0(col, debt);
uint256 fix1 = fix_calc_1(col, debt);
@@ -945,11 +975,12 @@ contract EndTest is DSTest {
// Assert on percentage error of returned collateral
wAssertCloseEnough(col0, col1);
}
+
function test_fuzz_fix_calcs_0_2(uint256 col_seed, uint192 debt_seed) public {
- uint256 col = col_seed % (115792 * WAD); // somewhat biased, but not enough to matter
- if (col < 10**12) col += 10**12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
+ uint256 col = col_seed % (115792 * WAD); // somewhat biased, but not enough to matter
+ if (col < 10 ** 12) col += 10 ** 12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
uint256 debt = debt_seed;
- if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
+ if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
uint256 fix0 = fix_calc_0(col, debt);
uint256 fix2 = fix_calc_2(col, debt);
@@ -961,11 +992,12 @@ contract EndTest is DSTest {
// Assert on percentage error of returned collateral
wAssertCloseEnough(col0, col2);
}
+
function test_fuzz_fix_calcs_1_2(uint256 col_seed, uint192 debt_seed) public {
- uint256 col = col_seed % (10**14 * WAD); // somewhat biased, but not enough to matter
- if (col < 10**12) col += 10**12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
+ uint256 col = col_seed % (10 ** 14 * WAD); // somewhat biased, but not enough to matter
+ if (col < 10 ** 12) col += 10 ** 12; // At least 10^-6 WAD units of collateral; this makes the fixes almost always non-zero.
uint256 debt = debt_seed;
- if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
+ if (debt < MIN_DEBT) debt += MIN_DEBT; // consider at least MIN_DEBT of debt
uint256 fix1 = fix_calc_1(col, debt);
uint256 fix2 = fix_calc_2(col, debt);
diff --git a/src/test/flap.t.sol b/src/test/flap.t.sol
index 112311f7..038d886b 100644
--- a/src/test/flap.t.sol
+++ b/src/test/flap.t.sol
@@ -24,39 +24,38 @@ import {DSToken} from "ds-token/token.sol";
import "../flap.sol";
import "../vat.sol";
-
interface Hevm {
function warp(uint256) external;
}
contract Guy {
Flapper flap;
+
constructor(Flapper flap_) public {
flap = flap_;
Vat(address(flap.vat())).hope(address(flap));
DSToken(address(flap.gem())).approve(address(flap));
}
- function tend(uint id, uint lot, uint bid) public {
+
+ function tend(uint256 id, uint256 lot, uint256 bid) public {
flap.tend(id, lot, bid);
}
- function deal(uint id) public {
+
+ function deal(uint256 id) public {
flap.deal(id);
}
- function try_tend(uint id, uint lot, uint bid)
- public returns (bool ok)
- {
+
+ function try_tend(uint256 id, uint256 lot, uint256 bid) public returns (bool ok) {
string memory sig = "tend(uint256,uint256,uint256)";
(ok,) = address(flap).call(abi.encodeWithSignature(sig, id, lot, bid));
}
- function try_deal(uint id)
- public returns (bool ok)
- {
+
+ function try_deal(uint256 id) public returns (bool ok) {
string memory sig = "deal(uint256)";
(ok,) = address(flap).call(abi.encodeWithSignature(sig, id));
}
- function try_tick(uint id)
- public returns (bool ok)
- {
+
+ function try_tick(uint256 id) public returns (bool ok) {
string memory sig = "tick(uint256)";
(ok,) = address(flap).call(abi.encodeWithSignature(sig, id));
}
@@ -66,7 +65,7 @@ contract FlapTest is DSTest {
Hevm hevm;
Flapper flap;
- Vat vat;
+ Vat vat;
DSToken gem;
address ali;
@@ -77,7 +76,7 @@ contract FlapTest is DSTest {
hevm.warp(604411200);
vat = new Vat();
- gem = new DSToken('');
+ gem = new DSToken("");
flap = new Flapper(address(vat), address(gem));
flap.file("lid", 500 ether);
@@ -96,21 +95,19 @@ contract FlapTest is DSTest {
gem.push(ali, 200 ether);
gem.push(bob, 200 ether);
}
+
function test_kick() public {
assertEq(vat.dai(address(this)), 1000 ether);
- assertEq(vat.dai(address(flap)), 0 ether);
- assertEq(flap.fill(), 0 ether);
- flap.kick({ lot: 100 ether
- , bid: 0
- });
- assertEq(vat.dai(address(this)), 900 ether);
- assertEq(vat.dai(address(flap)), 100 ether);
- assertEq(flap.fill(), 100 ether);
+ assertEq(vat.dai(address(flap)), 0 ether);
+ assertEq(flap.fill(), 0 ether);
+ flap.kick({lot: 100 ether, bid: 0});
+ assertEq(vat.dai(address(this)), 900 ether);
+ assertEq(vat.dai(address(flap)), 100 ether);
+ assertEq(flap.fill(), 100 ether);
}
+
function test_tend() public {
- uint id = flap.kick({ lot: 100 ether
- , bid: 0
- });
+ uint256 id = flap.kick({lot: 100 ether, bid: 0});
// lot taken from creator
assertEq(vat.dai(address(this)), 900 ether);
@@ -118,7 +115,7 @@ contract FlapTest is DSTest {
// bid taken from bidder
assertEq(gem.balanceOf(ali), 199 ether);
// payment remains in auction
- assertEq(gem.balanceOf(address(flap)), 1 ether);
+ assertEq(gem.balanceOf(address(flap)), 1 ether);
Guy(bob).tend(id, 100 ether, 2 ether);
// bid taken from bidder
@@ -126,97 +123,82 @@ contract FlapTest is DSTest {
// prev bidder refunded
assertEq(gem.balanceOf(ali), 200 ether);
// excess remains in auction
- assertEq(gem.balanceOf(address(flap)), 2 ether);
+ assertEq(gem.balanceOf(address(flap)), 2 ether);
hevm.warp(now + 5 weeks);
Guy(bob).deal(id);
// high bidder gets the lot
- assertEq(vat.dai(address(flap)), 0 ether);
+ assertEq(vat.dai(address(flap)), 0 ether);
assertEq(vat.dai(bob), 100 ether);
// income is burned
- assertEq(gem.balanceOf(address(flap)), 0 ether);
+ assertEq(gem.balanceOf(address(flap)), 0 ether);
}
+
function test_tend_same_bidder() public {
- uint id = flap.kick({ lot: 100 ether
- , bid: 0
- });
+ uint256 id = flap.kick({lot: 100 ether, bid: 0});
Guy(ali).tend(id, 100 ether, 190 ether);
assertEq(gem.balanceOf(ali), 10 ether);
Guy(ali).tend(id, 100 ether, 200 ether);
assertEq(gem.balanceOf(ali), 0);
}
+
function test_beg() public {
- uint id = flap.kick({ lot: 100 ether
- , bid: 0
- });
- assertTrue( Guy(ali).try_tend(id, 100 ether, 1.00 ether));
+ uint256 id = flap.kick({lot: 100 ether, bid: 0});
+ assertTrue(Guy(ali).try_tend(id, 100 ether, 1.0 ether));
assertTrue(!Guy(bob).try_tend(id, 100 ether, 1.01 ether));
// high bidder is subject to beg
assertTrue(!Guy(ali).try_tend(id, 100 ether, 1.01 ether));
- assertTrue( Guy(bob).try_tend(id, 100 ether, 1.07 ether));
+ assertTrue(Guy(bob).try_tend(id, 100 ether, 1.07 ether));
}
+
function test_tick() public {
// start an auction
- uint id = flap.kick({ lot: 100 ether
- , bid: 0
- });
+ uint256 id = flap.kick({lot: 100 ether, bid: 0});
// check no tick
assertTrue(!Guy(ali).try_tick(id));
// run past the end
hevm.warp(now + 2 weeks);
// check not biddable
assertTrue(!Guy(ali).try_tend(id, 100 ether, 1 ether));
- assertTrue( Guy(ali).try_tick(id));
+ assertTrue(Guy(ali).try_tick(id));
// check biddable
- assertTrue( Guy(ali).try_tend(id, 100 ether, 1 ether));
+ assertTrue(Guy(ali).try_tend(id, 100 ether, 1 ether));
}
+
function testFail_kick_over_lid() public {
- flap.kick({ lot: 501 ether
- , bid: 0
- });
+ flap.kick({lot: 501 ether, bid: 0});
}
+
function testFail_kick_over_lid_2_auctions() public {
// Just up to the lid
- flap.kick({ lot: 500 ether
- , bid: 0
- });
+ flap.kick({lot: 500 ether, bid: 0});
// Just over the lid
- flap.kick({ lot: 1
- , bid: 0
- });
+ flap.kick({lot: 1, bid: 0});
}
+
function test_deal() public {
- uint256 id = flap.kick({ lot: 400 ether
- , bid: 0
- });
+ uint256 id = flap.kick({lot: 400 ether, bid: 0});
assertEq(flap.fill(), 400 ether);
Guy(ali).tend(id, 400 ether, 1 ether);
assertEq(flap.fill(), 400 ether);
hevm.warp(block.timestamp + 30 days);
flap.deal(id);
assertEq(flap.fill(), 0);
- flap.kick({ lot: 400 ether
- , bid: 0
- });
+ flap.kick({lot: 400 ether, bid: 0});
assertEq(flap.fill(), 400 ether);
}
+
function test_multiple_auctions() public {
- uint256 id1 = flap.kick({ lot: 200 ether
- , bid: 0
- });
+ uint256 id1 = flap.kick({lot: 200 ether, bid: 0});
assertEq(flap.fill(), 200 ether);
- uint256 id2 = flap.kick({ lot: 200 ether
- , bid: 0
- });
+ uint256 id2 = flap.kick({lot: 200 ether, bid: 0});
assertEq(flap.fill(), 400 ether);
Guy(ali).tend(id1, 200 ether, 1 ether);
assertEq(flap.fill(), 400 ether);
hevm.warp(block.timestamp + 30 days);
flap.deal(id1);
assertEq(flap.fill(), 200 ether);
- flap.kick({ lot: 300 ether
- , bid: 0
- });
+ flap.kick({lot: 300 ether, bid: 0});
assertEq(flap.fill(), 500 ether);
flap.tick(id2);
Guy(ali).tend(id2, 200 ether, 1 ether);
@@ -225,10 +207,9 @@ contract FlapTest is DSTest {
flap.deal(id2);
assertEq(flap.fill(), 300 ether);
}
+
function test_mod_lid_in_flight() public {
- uint256 id = flap.kick({ lot: 400 ether
- , bid: 0
- });
+ uint256 id = flap.kick({lot: 400 ether, bid: 0});
assertEq(flap.fill(), 400 ether);
assertEq(flap.lid(), 500 ether);
@@ -241,10 +222,7 @@ contract FlapTest is DSTest {
hevm.warp(block.timestamp + 30 days);
flap.deal(id);
assertEq(flap.fill(), 0);
- flap.kick({ lot: 300 ether
- , bid: 0
- });
+ flap.kick({lot: 300 ether, bid: 0});
assertEq(flap.fill(), 300 ether);
}
-
}
diff --git a/src/test/flip.t.sol b/src/test/flip.t.sol
index f817fb45..836963ab 100644
--- a/src/test/flip.t.sol
+++ b/src/test/flip.t.sol
@@ -4,8 +4,8 @@ pragma solidity >=0.5.12;
import "ds-test/test.sol";
-import {Vat} from "../vat.sol";
-import {Cat} from "../cat.sol";
+import {Vat} from "../vat.sol";
+import {Cat} from "../cat.sol";
import {Flipper} from "../flip.sol";
interface Hevm {
@@ -14,77 +14,79 @@ interface Hevm {
contract Guy {
Flipper flip;
+
constructor(Flipper flip_) public {
flip = flip_;
}
+
function hope(address usr) public {
Vat(address(flip.vat())).hope(usr);
}
- function tend(uint id, uint lot, uint bid) public {
+
+ function tend(uint256 id, uint256 lot, uint256 bid) public {
flip.tend(id, lot, bid);
}
- function dent(uint id, uint lot, uint bid) public {
+
+ function dent(uint256 id, uint256 lot, uint256 bid) public {
flip.dent(id, lot, bid);
}
- function deal(uint id) public {
+
+ function deal(uint256 id) public {
flip.deal(id);
}
- function try_tend(uint id, uint lot, uint bid)
- public returns (bool ok)
- {
+
+ function try_tend(uint256 id, uint256 lot, uint256 bid) public returns (bool ok) {
string memory sig = "tend(uint256,uint256,uint256)";
(ok,) = address(flip).call(abi.encodeWithSignature(sig, id, lot, bid));
}
- function try_dent(uint id, uint lot, uint bid)
- public returns (bool ok)
- {
+
+ function try_dent(uint256 id, uint256 lot, uint256 bid) public returns (bool ok) {
string memory sig = "dent(uint256,uint256,uint256)";
(ok,) = address(flip).call(abi.encodeWithSignature(sig, id, lot, bid));
}
- function try_deal(uint id)
- public returns (bool ok)
- {
+
+ function try_deal(uint256 id) public returns (bool ok) {
string memory sig = "deal(uint256)";
(ok,) = address(flip).call(abi.encodeWithSignature(sig, id));
}
- function try_tick(uint id)
- public returns (bool ok)
- {
+
+ function try_tick(uint256 id) public returns (bool ok) {
string memory sig = "tick(uint256)";
(ok,) = address(flip).call(abi.encodeWithSignature(sig, id));
}
- function try_yank(uint id)
- public returns (bool ok)
- {
+
+ function try_yank(uint256 id) public returns (bool ok) {
string memory sig = "yank(uint256)";
(ok,) = address(flip).call(abi.encodeWithSignature(sig, id));
}
}
-
contract Gal {}
contract Cat_ is Cat {
- uint256 constant public RAD = 10 ** 45;
- uint256 constant public MLN = 10 ** 6;
+ uint256 public constant RAD = 10 ** 45;
+ uint256 public constant MLN = 10 ** 6;
- constructor(address vat_) Cat(vat_) public {
+ constructor(address vat_) public Cat(vat_) {
litter = 5 * MLN * RAD;
}
}
contract Vat_ is Vat {
- function mint(address usr, uint wad) public {
+ function mint(address usr, uint256 wad) public {
dai[usr] += wad;
}
- function dai_balance(address usr) public view returns (uint) {
+
+ function dai_balance(address usr) public view returns (uint256) {
return dai[usr];
}
bytes32 ilk;
+
function set_ilk(bytes32 ilk_) public {
ilk = ilk_;
}
- function gem_balance(address usr) public view returns (uint) {
+
+ function gem_balance(address usr) public view returns (uint256) {
return gem[ilk][usr];
}
}
@@ -92,8 +94,8 @@ contract Vat_ is Vat {
contract FlipTest is DSTest {
Hevm hevm;
- Vat_ vat;
- Cat_ cat;
+ Vat_ vat;
+ Cat_ cat;
Flipper flip;
address ali;
@@ -101,9 +103,9 @@ contract FlipTest is DSTest {
address gal;
address usr = address(0xacab);
- uint256 constant public RAY = 10 ** 27;
- uint256 constant public RAD = 10 ** 45;
- uint256 constant public MLN = 10 ** 6;
+ uint256 public constant RAY = 10 ** 27;
+ uint256 public constant RAD = 10 ** 45;
+ uint256 public constant MLN = 10 ** 6;
function setUp() public {
hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
@@ -130,34 +132,28 @@ contract FlipTest is DSTest {
vat.mint(ali, 200 ether);
vat.mint(bob, 200 ether);
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
+
function test_kick() public {
- flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
}
+
function testFail_tend_empty() public {
// can't tend on non-existent
flip.tend(42, 0, 0);
}
+
function test_tend() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
Guy(ali).tend(id, 100 ether, 1 ether);
// bid taken from bidder
- assertEq(vat.dai_balance(ali), 199 ether);
+ assertEq(vat.dai_balance(ali), 199 ether);
// gal receives payment
- assertEq(vat.dai_balance(gal), 1 ether);
+ assertEq(vat.dai_balance(gal), 1 ether);
Guy(bob).tend(id, 100 ether, 2 ether);
// bid taken from bidder
@@ -165,51 +161,39 @@ contract FlipTest is DSTest {
// prev bidder refunded
assertEq(vat.dai_balance(ali), 200 ether);
// gal receives excess
- assertEq(vat.dai_balance(gal), 2 ether);
+ assertEq(vat.dai_balance(gal), 2 ether);
hevm.warp(now + 5 hours);
Guy(bob).deal(id);
// bob gets the winnings
assertEq(vat.gem_balance(bob), 100 ether);
}
+
function test_tend_later() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
hevm.warp(now + 5 hours);
Guy(ali).tend(id, 100 ether, 1 ether);
// bid taken from bidder
assertEq(vat.dai_balance(ali), 199 ether);
// gal receives payment
- assertEq(vat.dai_balance(gal), 1 ether);
+ assertEq(vat.dai_balance(gal), 1 ether);
}
+
function test_dent() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
- Guy(ali).tend(id, 100 ether, 1 ether);
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
+ Guy(ali).tend(id, 100 ether, 1 ether);
Guy(bob).tend(id, 100 ether, 50 ether);
- Guy(ali).dent(id, 95 ether, 50 ether);
+ Guy(ali).dent(id, 95 ether, 50 ether);
// plop the gems
assertEq(vat.gem_balance(address(0xacab)), 5 ether);
- assertEq(vat.dai_balance(ali), 150 ether);
- assertEq(vat.dai_balance(bob), 200 ether);
+ assertEq(vat.dai_balance(ali), 150 ether);
+ assertEq(vat.dai_balance(bob), 200 ether);
}
+
function test_tend_dent_same_bidder() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 200 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 200 ether, usr: usr, gal: gal, bid: 0});
assertEq(vat.dai_balance(ali), 200 ether);
Guy(ali).tend(id, 100 ether, 190 ether);
@@ -218,101 +202,76 @@ contract FlipTest is DSTest {
assertEq(vat.dai_balance(ali), 0);
Guy(ali).dent(id, 80 ether, 200 ether);
}
+
function test_beg() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
- assertTrue( Guy(ali).try_tend(id, 100 ether, 1.00 ether));
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
+ assertTrue(Guy(ali).try_tend(id, 100 ether, 1.0 ether));
assertTrue(!Guy(bob).try_tend(id, 100 ether, 1.01 ether));
// high bidder is subject to beg
assertTrue(!Guy(ali).try_tend(id, 100 ether, 1.01 ether));
- assertTrue( Guy(bob).try_tend(id, 100 ether, 1.07 ether));
+ assertTrue(Guy(bob).try_tend(id, 100 ether, 1.07 ether));
// can bid by less than beg at flip
- assertTrue( Guy(ali).try_tend(id, 100 ether, 49 ether));
- assertTrue( Guy(bob).try_tend(id, 100 ether, 50 ether));
+ assertTrue(Guy(ali).try_tend(id, 100 ether, 49 ether));
+ assertTrue(Guy(bob).try_tend(id, 100 ether, 50 ether));
assertTrue(!Guy(ali).try_dent(id, 100 ether, 50 ether));
- assertTrue(!Guy(ali).try_dent(id, 99 ether, 50 ether));
- assertTrue( Guy(ali).try_dent(id, 95 ether, 50 ether));
+ assertTrue(!Guy(ali).try_dent(id, 99 ether, 50 ether));
+ assertTrue(Guy(ali).try_dent(id, 95 ether, 50 ether));
}
+
function test_deal() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
// only after ttl
Guy(ali).tend(id, 100 ether, 1 ether);
assertTrue(!Guy(bob).try_deal(id));
hevm.warp(now + 4.1 hours);
- assertTrue( Guy(bob).try_deal(id));
+ assertTrue(Guy(bob).try_deal(id));
- uint ie = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 ie = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
// or after end
hevm.warp(now + 44 hours);
Guy(ali).tend(ie, 100 ether, 1 ether);
assertTrue(!Guy(bob).try_deal(ie));
hevm.warp(now + 1 days);
- assertTrue( Guy(bob).try_deal(ie));
+ assertTrue(Guy(bob).try_deal(ie));
}
+
function test_tick() public {
// start an auction
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
// check no tick
assertTrue(!Guy(ali).try_tick(id));
// run past the end
hevm.warp(now + 2 weeks);
// check not biddable
assertTrue(!Guy(ali).try_tend(id, 100 ether, 1 ether));
- assertTrue( Guy(ali).try_tick(id));
+ assertTrue(Guy(ali).try_tick(id));
// check biddable
- assertTrue( Guy(ali).try_tend(id, 100 ether, 1 ether));
+ assertTrue(Guy(ali).try_tend(id, 100 ether, 1 ether));
}
+
function test_no_deal_after_end() public {
// if there are no bids and the auction ends, then it should not
// be refundable to the creator. Rather, it ticks indefinitely.
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
assertTrue(!Guy(ali).try_deal(id));
hevm.warp(now + 2 weeks);
assertTrue(!Guy(ali).try_deal(id));
- assertTrue( Guy(ali).try_tick(id));
+ assertTrue(Guy(ali).try_tick(id));
assertTrue(!Guy(ali).try_deal(id));
}
+
function test_yank_tend() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: rad(50 ether)
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: rad(50 ether), usr: usr, gal: gal, bid: 0});
Guy(ali).tend(id, 100 ether, 1 ether);
// bid taken from bidder
assertEq(vat.dai_balance(ali), 199 ether);
- assertEq(vat.dai_balance(gal), 1 ether);
+ assertEq(vat.dai_balance(gal), 1 ether);
// we have some amount of litter in the box
assertEq(cat.litter(), 5 * MLN * RAD);
@@ -321,8 +280,8 @@ contract FlipTest is DSTest {
flip.yank(id);
// bid is refunded to bidder from caller
- assertEq(vat.dai_balance(ali), 200 ether);
- assertEq(vat.dai_balance(address(this)), 0 ether);
+ assertEq(vat.dai_balance(ali), 200 ether);
+ assertEq(vat.dai_balance(address(this)), 0 ether);
// gems go to caller
assertEq(vat.gem_balance(address(this)), 1000 ether);
@@ -330,20 +289,16 @@ contract FlipTest is DSTest {
// cat.scoop(tab) is called decrementing the litter accumulator
assertEq(cat.litter(), (5 * MLN * RAD) - rad(50 ether));
}
+
function test_yank_dent() public {
- uint id = flip.kick({ lot: 100 ether
- , tab: 50 ether
- , usr: usr
- , gal: gal
- , bid: 0
- });
+ uint256 id = flip.kick({lot: 100 ether, tab: 50 ether, usr: usr, gal: gal, bid: 0});
// we have some amount of litter in the box
assertEq(cat.litter(), 5 * MLN * RAD);
- Guy(ali).tend(id, 100 ether, 1 ether);
+ Guy(ali).tend(id, 100 ether, 1 ether);
Guy(bob).tend(id, 100 ether, 50 ether);
- Guy(ali).dent(id, 95 ether, 50 ether);
+ Guy(ali).dent(id, 95 ether, 50 ether);
// cannot yank in the dent phase
assertTrue(!Guy(ali).try_yank(id));
diff --git a/src/test/flop.t.sol b/src/test/flop.t.sol
index ce866ab6..d7596f2b 100644
--- a/src/test/flop.t.sol
+++ b/src/test/flop.t.sol
@@ -17,73 +17,78 @@
pragma solidity ^0.6.12;
-import {DSTest} from "ds-test/test.sol";
+import {DSTest} from "ds-test/test.sol";
import {DSToken} from "ds-token/token.sol";
import "../flop.sol";
import "../vat.sol";
-
interface Hevm {
function warp(uint256) external;
}
contract Guy {
Flopper flop;
+
constructor(Flopper flop_) public {
flop = flop_;
Vat(address(flop.vat())).hope(address(flop));
DSToken(address(flop.gem())).approve(address(flop));
}
- function dent(uint id, uint lot, uint bid) public {
+
+ function dent(uint256 id, uint256 lot, uint256 bid) public {
flop.dent(id, lot, bid);
}
- function deal(uint id) public {
+
+ function deal(uint256 id) public {
flop.deal(id);
}
- function try_dent(uint id, uint lot, uint bid)
- public returns (bool ok)
- {
+
+ function try_dent(uint256 id, uint256 lot, uint256 bid) public returns (bool ok) {
string memory sig = "dent(uint256,uint256,uint256)";
(ok,) = address(flop).call(abi.encodeWithSignature(sig, id, lot, bid));
}
- function try_deal(uint id)
- public returns (bool ok)
- {
+
+ function try_deal(uint256 id) public returns (bool ok) {
string memory sig = "deal(uint256)";
(ok,) = address(flop).call(abi.encodeWithSignature(sig, id));
}
- function try_tick(uint id)
- public returns (bool ok)
- {
+
+ function try_tick(uint256 id) public returns (bool ok) {
string memory sig = "tick(uint256)";
(ok,) = address(flop).call(abi.encodeWithSignature(sig, id));
}
}
contract Gal {
- uint public Ash;
- function sub(uint x, uint y) internal pure returns (uint z) {
+ uint256 public Ash;
+
+ function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
- function kick(Flopper flop, uint lot, uint bid) external returns (uint) {
+
+ function kick(Flopper flop, uint256 lot, uint256 bid) external returns (uint256) {
Ash += bid;
return flop.kick(address(this), lot, bid);
}
- function kiss(uint rad) external {
+
+ function kiss(uint256 rad) external {
Ash = sub(Ash, rad);
}
+
function cage(Flopper flop) external {
flop.cage();
}
}
-contract Vatish is DSToken('') {
- uint constant ONE = 10 ** 27;
+contract Vatish is DSToken("") {
+ uint256 constant ONE = 10 ** 27;
+
function hope(address usr) public {
- approve(usr, uint(-1));
+ approve(usr, uint256(-1));
}
- function dai(address usr) public view returns (uint) {
- return balanceOf[usr];
+
+ function dai(address usr) public view returns (uint256) {
+ return balanceOf[usr];
}
}
@@ -91,21 +96,21 @@ contract FlopTest is DSTest {
Hevm hevm;
Flopper flop;
- Vat vat;
+ Vat vat;
DSToken gem;
address ali;
address bob;
address gal;
- function kiss(uint) public pure { } // arbitrary callback
+ function kiss(uint256) public pure {} // arbitrary callback
function setUp() public {
hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
hevm.warp(604411200);
vat = new Vat();
- gem = new DSToken('');
+ gem = new DSToken("");
flop = new Flopper(address(vat), address(gem));
@@ -129,7 +134,14 @@ contract FlopTest is DSTest {
function test_kick() public {
assertEq(vat.dai(gal), 0);
assertEq(gem.balanceOf(gal), 0 ether);
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 5000 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 5000 ether
+ );
// no value transferred
assertEq(vat.dai(gal), 0);
assertEq(gem.balanceOf(gal), 0 ether);
@@ -144,13 +156,20 @@ contract FlopTest is DSTest {
}
function test_dent() public {
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
Guy(ali).dent(id, 100 ether, 10 ether);
// bid taken from bidder
assertEq(vat.dai(ali), 190 ether);
// gal receives payment
- assertEq(vat.dai(gal), 10 ether);
+ assertEq(vat.dai(gal), 10 ether);
assertEq(Gal(gal).Ash(), 0 ether);
Guy(bob).dent(id, 80 ether, 10 ether);
@@ -162,7 +181,7 @@ contract FlopTest is DSTest {
assertEq(vat.dai(gal), 10 ether);
hevm.warp(now + 5 weeks);
- assertEq(gem.totalSupply(), 0 ether);
+ assertEq(gem.totalSupply(), 0 ether);
gem.setOwner(address(flop));
Guy(bob).deal(id);
// gems minted on demand
@@ -172,8 +191,15 @@ contract FlopTest is DSTest {
}
function test_dent_Ash_less_than_bid() public {
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
- assertEq(vat.dai(gal), 0 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
+ assertEq(vat.dai(gal), 0 ether);
Gal(gal).kiss(1 ether);
assertEq(Gal(gal).Ash(), 9 ether);
@@ -182,7 +208,7 @@ contract FlopTest is DSTest {
// bid taken from bidder
assertEq(vat.dai(ali), 190 ether);
// gal receives payment
- assertEq(vat.dai(gal), 10 ether);
+ assertEq(vat.dai(gal), 10 ether);
assertEq(Gal(gal).Ash(), 0 ether);
Guy(bob).dent(id, 80 ether, 10 ether);
@@ -194,7 +220,7 @@ contract FlopTest is DSTest {
assertEq(vat.dai(gal), 10 ether);
hevm.warp(now + 5 weeks);
- assertEq(gem.totalSupply(), 0 ether);
+ assertEq(gem.totalSupply(), 0 ether);
gem.setOwner(address(flop));
Guy(bob).deal(id);
// gems minted on demand
@@ -204,7 +230,14 @@ contract FlopTest is DSTest {
}
function test_dent_same_bidder() public {
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 200 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 200 ether
+ );
Guy(ali).dent(id, 100 ether, 200 ether);
assertEq(vat.dai(ali), 0);
@@ -213,29 +246,43 @@ contract FlopTest is DSTest {
function test_tick() public {
// start an auction
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
// check no tick
assertTrue(!Guy(ali).try_tick(id));
// run past the end
hevm.warp(now + 2 weeks);
// check not biddable
assertTrue(!Guy(ali).try_dent(id, 100 ether, 10 ether));
- assertTrue( Guy(ali).try_tick(id));
+ assertTrue(Guy(ali).try_tick(id));
// check biddable
- (, uint _lot,,,) = flop.bids(id);
+ (, uint256 _lot,,,) = flop.bids(id);
// tick should increase the lot by pad (50%) and restart the auction
assertEq(_lot, 300 ether);
- assertTrue( Guy(ali).try_dent(id, 100 ether, 10 ether));
+ assertTrue(Guy(ali).try_dent(id, 100 ether, 10 ether));
}
function test_no_deal_after_end() public {
// if there are no bids and the auction ends, then it should not
// be refundable to the creator. Rather, it ticks indefinitely.
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
assertTrue(!Guy(ali).try_deal(id));
hevm.warp(now + 2 weeks);
assertTrue(!Guy(ali).try_deal(id));
- assertTrue( Guy(ali).try_tick(id));
+ assertTrue(Guy(ali).try_tick(id));
assertTrue(!Guy(ali).try_deal(id));
}
@@ -243,7 +290,14 @@ contract FlopTest is DSTest {
// yanking the auction should refund the last bidder's dai, credit a
// corresponding amount of sin to the caller of cage, and delete the auction.
// in practice, gal == (caller of cage) == (vow address)
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
// confrim initial state expectations
assertEq(vat.dai(ali), 200 ether);
@@ -255,9 +309,9 @@ contract FlopTest is DSTest {
Guy(bob).dent(id, 80 ether, 10 ether);
// confirm the proper state updates have occurred
- assertEq(vat.dai(ali), 200 ether); // ali's dai balance is unchanged
+ assertEq(vat.dai(ali), 200 ether); // ali's dai balance is unchanged
assertEq(vat.dai(bob), 190 ether);
- assertEq(vat.dai(gal), 10 ether);
+ assertEq(vat.dai(gal), 10 ether);
assertEq(vat.sin(address(this)), 1000 ether);
Gal(gal).cage(flop);
@@ -265,9 +319,9 @@ contract FlopTest is DSTest {
// confirm final state
assertEq(vat.dai(ali), 200 ether);
- assertEq(vat.dai(bob), 200 ether); // bob's bid has been refunded
- assertEq(vat.dai(gal), 10 ether);
- assertEq(vat.sin(gal), 10 ether); // sin assigned to caller of cage()
+ assertEq(vat.dai(bob), 200 ether); // bob's bid has been refunded
+ assertEq(vat.dai(gal), 10 ether);
+ assertEq(vat.sin(gal), 10 ether); // sin assigned to caller of cage()
(uint256 _bid, uint256 _lot, address _guy, uint48 _tic, uint48 _end) = flop.bids(id);
assertEq(_bid, 0);
assertEq(_lot, 0);
@@ -280,7 +334,14 @@ contract FlopTest is DSTest {
// with no bidder to refund, yanking the auction should simply create equal
// amounts of dai (credited to the gal) and sin (credited to the caller of cage)
// in practice, gal == (caller of cage) == (vow address)
- uint id = Gal(gal).kick(flop, /*lot*/ 200 ether, /*bid*/ 10 ether);
+ uint256 id = Gal(gal)
+ .kick(
+ flop,
+ /*lot*/
+ 200 ether,
+ /*bid*/
+ 10 ether
+ );
// confrim initial state expectations
assertEq(vat.dai(ali), 200 ether);
@@ -294,8 +355,8 @@ contract FlopTest is DSTest {
// confirm final state
assertEq(vat.dai(ali), 200 ether);
assertEq(vat.dai(bob), 200 ether);
- assertEq(vat.dai(gal), 10 ether);
- assertEq(vat.sin(gal), 10 ether); // sin assigned to caller of cage()
+ assertEq(vat.dai(gal), 10 ether);
+ assertEq(vat.sin(gal), 10 ether); // sin assigned to caller of cage()
(uint256 _bid, uint256 _lot, address _guy, uint48 _tic, uint48 _end) = flop.bids(id);
assertEq(_bid, 0);
assertEq(_lot, 0);
diff --git a/src/test/fork.t.sol b/src/test/fork.t.sol
index 91f37aae..cddfaaa2 100644
--- a/src/test/fork.t.sol
+++ b/src/test/fork.t.sol
@@ -20,13 +20,15 @@ pragma solidity ^0.6.12;
import "ds-test/test.sol";
import "ds-token/token.sol";
-import {Vat} from '../vat.sol';
+import {Vat} from "../vat.sol";
contract Usr {
Vat public vat;
+
constructor(Vat vat_) public {
vat = vat_;
}
+
function try_call(address addr, bytes calldata data) external returns (bool) {
bytes memory _data = data;
assembly {
@@ -37,7 +39,8 @@ contract Usr {
revert(free, 32)
}
}
- function can_frob(bytes32 ilk, address u, address v, address w, int dink, int dart) public returns (bool) {
+
+ function can_frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) public returns (bool) {
string memory sig = "frob(bytes32,address,address,address,int256,int256)";
bytes memory data = abi.encodeWithSignature(sig, ilk, u, v, w, dink, dart);
@@ -47,7 +50,8 @@ contract Usr {
ok = abi.decode(success, (bool));
if (ok) return true;
}
- function can_fork(bytes32 ilk, address src, address dst, int dink, int dart) public returns (bool) {
+
+ function can_fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) public returns (bool) {
string memory sig = "fork(bytes32,address,address,int256,int256)";
bytes memory data = abi.encodeWithSignature(sig, ilk, src, dst, dink, dart);
@@ -57,12 +61,15 @@ contract Usr {
ok = abi.decode(success, (bool));
if (ok) return true;
}
- function frob(bytes32 ilk, address u, address v, address w, int dink, int dart) public {
+
+ function frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) public {
vat.frob(ilk, u, v, w, dink, dart);
}
- function fork(bytes32 ilk, address src, address dst, int dink, int dart) public {
+
+ function fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) public {
vat.fork(ilk, src, dst, dink, dart);
}
+
function hope(address usr) public {
vat.hope(usr);
}
@@ -76,10 +83,11 @@ contract ForkTest is DSTest {
address a;
address b;
- function ray(uint wad) internal pure returns (uint) {
+ function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
@@ -91,37 +99,41 @@ contract ForkTest is DSTest {
b = address(bob);
vat.init("gems");
- vat.file("gems", "spot", ray(0.5 ether));
+ vat.file("gems", "spot", ray(0.5 ether));
vat.file("gems", "line", rad(1000 ether));
- vat.file("Line", rad(1000 ether));
+ vat.file("Line", rad(1000 ether));
vat.slip("gems", a, 8 ether);
}
+
function test_fork_to_self() public {
ali.frob("gems", a, a, a, 8 ether, 4 ether);
- assertTrue( ali.can_fork("gems", a, a, 8 ether, 4 ether));
- assertTrue( ali.can_fork("gems", a, a, 4 ether, 2 ether));
+ assertTrue(ali.can_fork("gems", a, a, 8 ether, 4 ether));
+ assertTrue(ali.can_fork("gems", a, a, 4 ether, 2 ether));
assertTrue(!ali.can_fork("gems", a, a, 9 ether, 4 ether));
}
+
function test_give_to_other() public {
ali.frob("gems", a, a, a, 8 ether, 4 ether);
assertTrue(!ali.can_fork("gems", a, b, 8 ether, 4 ether));
bob.hope(address(ali));
- assertTrue( ali.can_fork("gems", a, b, 8 ether, 4 ether));
+ assertTrue(ali.can_fork("gems", a, b, 8 ether, 4 ether));
}
+
function test_fork_to_other() public {
ali.frob("gems", a, a, a, 8 ether, 4 ether);
bob.hope(address(ali));
- assertTrue( ali.can_fork("gems", a, b, 4 ether, 2 ether));
+ assertTrue(ali.can_fork("gems", a, b, 4 ether, 2 ether));
assertTrue(!ali.can_fork("gems", a, b, 4 ether, 3 ether));
assertTrue(!ali.can_fork("gems", a, b, 4 ether, 1 ether));
}
+
function test_fork_dust() public {
ali.frob("gems", a, a, a, 8 ether, 4 ether);
bob.hope(address(ali));
- assertTrue( ali.can_fork("gems", a, b, 4 ether, 2 ether));
+ assertTrue(ali.can_fork("gems", a, b, 4 ether, 2 ether));
vat.file("gems", "dust", rad(1 ether));
- assertTrue( ali.can_fork("gems", a, b, 2 ether, 1 ether));
+ assertTrue(ali.can_fork("gems", a, b, 2 ether, 1 ether));
assertTrue(!ali.can_fork("gems", a, b, 1 ether, 0.5 ether));
}
}
diff --git a/src/test/jug.t.sol b/src/test/jug.t.sol
index f5395d4b..3a118b0d 100644
--- a/src/test/jug.t.sol
+++ b/src/test/jug.t.sol
@@ -22,52 +22,50 @@ import "ds-test/test.sol";
import {Jug} from "../jug.sol";
import {Vat} from "../vat.sol";
-
interface Hevm {
function warp(uint256) external;
}
interface VatLike {
- function ilks(bytes32) external view returns (
- uint256 Art,
- uint256 rate,
- uint256 spot,
- uint256 line,
- uint256 dust
- );
+ function ilks(bytes32) external view returns (uint256 Art, uint256 rate, uint256 spot, uint256 line, uint256 dust);
}
contract Rpow is Jug {
- constructor(address vat_) public Jug(vat_){}
+ constructor(address vat_) public Jug(vat_) {}
- function pRpow(uint x, uint n, uint b) public pure returns(uint) {
+ function pRpow(uint256 x, uint256 n, uint256 b) public pure returns (uint256) {
return _rpow(x, n, b);
}
}
-
contract JugTest is DSTest {
Hevm hevm;
Jug jug;
- Vat vat;
+ Vat vat;
- function rad(uint wad_) internal pure returns (uint) {
+ function rad(uint256 wad_) internal pure returns (uint256) {
return wad_ * 10 ** 27;
}
- function wad(uint rad_) internal pure returns (uint) {
+
+ function wad(uint256 rad_) internal pure returns (uint256) {
return rad_ / 10 ** 27;
}
- function rho(bytes32 ilk) internal view returns (uint) {
- (uint duty, uint rho_) = jug.ilks(ilk); duty;
+
+ function rho(bytes32 ilk) internal view returns (uint256) {
+ (uint256 duty, uint256 rho_) = jug.ilks(ilk);
+ duty;
return rho_;
}
- function Art(bytes32 ilk) internal view returns (uint ArtV) {
+
+ function Art(bytes32 ilk) internal view returns (uint256 ArtV) {
(ArtV,,,,) = VatLike(address(vat)).ilks(ilk);
}
- function rate(bytes32 ilk) internal view returns (uint rateV) {
+
+ function rate(bytes32 ilk) internal view returns (uint256 rateV) {
(, rateV,,,) = VatLike(address(vat)).ilks(ilk);
}
- function line(bytes32 ilk) internal view returns (uint lineV) {
+
+ function line(bytes32 ilk) internal view returns (uint256 lineV) {
(,,, lineV,) = VatLike(address(vat)).ilks(ilk);
}
@@ -77,31 +75,33 @@ contract JugTest is DSTest {
hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
hevm.warp(604411200);
- vat = new Vat();
+ vat = new Vat();
jug = new Jug(address(vat));
vat.rely(address(jug));
vat.init("i");
draw("i", 100 ether);
}
- function draw(bytes32 ilk, uint dai) internal {
+
+ function draw(bytes32 ilk, uint256 dai) internal {
vat.file("Line", vat.Line() + rad(dai));
vat.file(ilk, "line", line(ilk) + rad(dai));
vat.file(ilk, "spot", 10 ** 27 * 10000 ether);
address self = address(this);
- vat.slip(ilk, self, 10 ** 27 * 1 ether);
- vat.frob(ilk, self, self, self, int(1 ether), int(dai));
+ vat.slip(ilk, self, 10 ** 27 * 1 ether);
+ vat.frob(ilk, self, self, self, int256(1 ether), int256(dai));
}
function test_drip_setup() public {
hevm.warp(0);
- assertEq(uint(now), 0);
+ assertEq(uint256(now), 0);
hevm.warp(1);
- assertEq(uint(now), 1);
+ assertEq(uint256(now), 1);
hevm.warp(2);
- assertEq(uint(now), 2);
+ assertEq(uint256(now), 2);
assertEq(Art("i"), 100 ether);
}
+
function test_drip_updates_rho() public {
jug.init("i");
assertEq(rho("i"), now);
@@ -117,54 +117,60 @@ contract JugTest is DSTest {
jug.drip("i");
assertEq(rho("i"), now);
}
+
function test_drip_file() public {
jug.init("i");
jug.file("i", "duty", 10 ** 27);
jug.drip("i");
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
}
+
function test_drip_0d() public {
jug.init("i");
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
assertEq(vat.dai(ali), rad(0 ether));
jug.drip("i");
assertEq(vat.dai(ali), rad(0 ether));
}
+
function test_drip_1d() public {
jug.init("i");
jug.file("vow", ali);
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
hevm.warp(now + 1 days);
assertEq(wad(vat.dai(ali)), 0 ether);
jug.drip("i");
assertEq(wad(vat.dai(ali)), 5 ether);
}
+
function test_drip_2d() public {
jug.init("i");
jug.file("vow", ali);
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
hevm.warp(now + 2 days);
assertEq(wad(vat.dai(ali)), 0 ether);
jug.drip("i");
assertEq(wad(vat.dai(ali)), 10.25 ether);
}
+
function test_drip_3d() public {
jug.init("i");
jug.file("vow", ali);
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
hevm.warp(now + 3 days);
assertEq(wad(vat.dai(ali)), 0 ether);
jug.drip("i");
assertEq(wad(vat.dai(ali)), 15.7625 ether);
}
+
function test_drip_negative_3d() public {
jug.init("i");
jug.file("vow", ali);
- jug.file("i", "duty", 999999706969857929985428567); // -2.5% / day
+ jug.file("i", "duty", 999999706969857929985428567); // -2.5% / day
hevm.warp(now + 3 days);
assertEq(wad(vat.dai(address(this))), 100 ether);
vat.move(address(this), ali, rad(100 ether));
@@ -177,17 +183,18 @@ contract JugTest is DSTest {
jug.init("i");
jug.file("vow", ali);
- jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
+ jug.file("i", "duty", 1000000564701133626865910626); // 5% / day
hevm.warp(now + 1 days);
jug.drip("i");
assertEq(wad(vat.dai(ali)), 5 ether);
- jug.file("i", "duty", 1000001103127689513476993127); // 10% / day
+ jug.file("i", "duty", 1000001103127689513476993127); // 10% / day
hevm.warp(now + 1 days);
jug.drip("i");
- assertEq(wad(vat.dai(ali)), 15.5 ether);
- assertEq(wad(vat.debt()), 115.5 ether);
+ assertEq(wad(vat.dai(ali)), 15.5 ether);
+ assertEq(wad(vat.debt()), 115.5 ether);
assertEq(rate("i") / 10 ** 9, 1.155 ether);
}
+
function test_drip_base() public {
vat.init("j");
draw("j", 100 ether);
@@ -196,29 +203,32 @@ contract JugTest is DSTest {
jug.init("j");
jug.file("vow", ali);
- jug.file("i", "duty", 1050000000000000000000000000); // 5% / second
- jug.file("j", "duty", 1000000000000000000000000000); // 0% / second
- jug.file("base", uint(50000000000000000000000000)); // 5% / second
+ jug.file("i", "duty", 1050000000000000000000000000); // 5% / second
+ jug.file("j", "duty", 1000000000000000000000000000); // 0% / second
+ jug.file("base", uint256(50000000000000000000000000)); // 5% / second
hevm.warp(now + 1);
jug.drip("i");
assertEq(wad(vat.dai(ali)), 10 ether);
}
+
function test_file_duty() public {
jug.init("i");
hevm.warp(now + 1);
jug.drip("i");
jug.file("i", "duty", 1);
}
+
function testFail_file_duty() public {
jug.init("i");
hevm.warp(now + 1);
jug.file("i", "duty", 1);
}
+
function test_rpow() public {
Rpow r = new Rpow(address(vat));
- uint result = r.pRpow(uint(1000234891009084238901289093), uint(3724), uint(1e27));
+ uint256 result = r.pRpow(uint256(1000234891009084238901289093), uint256(3724), uint256(1e27));
// python calc = 2.397991232255757e27 = 2397991232255757e12
// expect 10 decimal precision
- assertEq(result / uint(1e17), uint(2397991232255757e12) / 1e17);
+ assertEq(result / uint256(1e17), uint256(2397991232255757e12) / 1e17);
}
}
diff --git a/src/test/pot.t.sol b/src/test/pot.t.sol
index 26dacaa9..229988f0 100644
--- a/src/test/pot.t.sol
+++ b/src/test/pot.t.sol
@@ -18,8 +18,8 @@
pragma solidity ^0.6.12;
import "ds-test/test.sol";
-import {Vat} from '../vat.sol';
-import {Pot} from '../pot.sol';
+import {Vat} from "../vat.sol";
+import {Pot} from "../pot.sol";
interface Hevm {
function warp(uint256) external;
@@ -35,10 +35,11 @@ contract DSRTest is DSTest {
address self;
address potb;
- function rad(uint wad_) internal pure returns (uint) {
+ function rad(uint256 wad_) internal pure returns (uint256) {
return wad_ * 10 ** 27;
}
- function wad(uint rad_) internal pure returns (uint) {
+
+ function wad(uint256 rad_) internal pure returns (uint256) {
return rad_ / 10 ** 27;
}
@@ -58,44 +59,48 @@ contract DSRTest is DSTest {
vat.suck(self, self, rad(100 ether));
vat.hope(address(pot));
}
+
function test_save_0d() public {
assertEq(vat.dai(self), rad(100 ether));
pot.join(100 ether);
- assertEq(wad(vat.dai(self)), 0 ether);
- assertEq(pot.pie(self), 100 ether);
+ assertEq(wad(vat.dai(self)), 0 ether);
+ assertEq(pot.pie(self), 100 ether);
pot.drip();
pot.exit(100 ether);
assertEq(wad(vat.dai(self)), 100 ether);
}
+
function test_save_1d() public {
pot.join(100 ether);
- pot.file("dsr", uint(1000000564701133626865910626)); // 5% / day
+ pot.file("dsr", uint256(1000000564701133626865910626)); // 5% / day
hevm.warp(now + 1 days);
pot.drip();
assertEq(pot.pie(self), 100 ether);
pot.exit(100 ether);
assertEq(wad(vat.dai(self)), 105 ether);
}
+
function test_drip_multi() public {
pot.join(100 ether);
- pot.file("dsr", uint(1000000564701133626865910626)); // 5% / day
+ pot.file("dsr", uint256(1000000564701133626865910626)); // 5% / day
hevm.warp(now + 1 days);
pot.drip();
- assertEq(wad(vat.dai(potb)), 105 ether);
- pot.file("dsr", uint(1000001103127689513476993127)); // 10% / day
+ assertEq(wad(vat.dai(potb)), 105 ether);
+ pot.file("dsr", uint256(1000001103127689513476993127)); // 10% / day
hevm.warp(now + 1 days);
pot.drip();
assertEq(wad(vat.sin(vow)), 15.5 ether);
assertEq(wad(vat.dai(potb)), 115.5 ether);
- assertEq(pot.Pie(), 100 ether);
+ assertEq(pot.Pie(), 100 ether);
assertEq(pot.chi() / 10 ** 9, 1.155 ether);
}
+
function test_drip_multi_inBlock() public {
pot.drip();
- uint rho = pot.rho();
+ uint256 rho = pot.rho();
assertEq(rho, now);
hevm.warp(now + 1 days);
rho = pot.rho();
@@ -107,24 +112,26 @@ contract DSRTest is DSTest {
rho = pot.rho();
assertEq(rho, now);
}
+
function test_save_multi() public {
pot.join(100 ether);
- pot.file("dsr", uint(1000000564701133626865910626)); // 5% / day
+ pot.file("dsr", uint256(1000000564701133626865910626)); // 5% / day
hevm.warp(now + 1 days);
pot.drip();
pot.exit(50 ether);
assertEq(wad(vat.dai(self)), 52.5 ether);
- assertEq(pot.Pie(), 50.0 ether);
+ assertEq(pot.Pie(), 50.0 ether);
- pot.file("dsr", uint(1000001103127689513476993127)); // 10% / day
+ pot.file("dsr", uint256(1000001103127689513476993127)); // 10% / day
hevm.warp(now + 1 days);
pot.drip();
pot.exit(50 ether);
assertEq(wad(vat.dai(self)), 110.25 ether);
- assertEq(pot.Pie(), 0.00 ether);
+ assertEq(pot.Pie(), 0.0 ether);
}
+
function test_fresh_chi() public {
- uint rho = pot.rho();
+ uint256 rho = pot.rho();
assertEq(rho, now);
hevm.warp(now + 1 days);
assertEq(rho, now - 1 days);
@@ -135,19 +142,22 @@ contract DSRTest is DSTest {
// if we exit in the same transaction we should not earn DSR
assertEq(wad(vat.dai(self)), 100 ether);
}
+
function testFail_stale_chi() public {
- pot.file("dsr", uint(1000000564701133626865910626)); // 5% / day
+ pot.file("dsr", uint256(1000000564701133626865910626)); // 5% / day
pot.drip();
hevm.warp(now + 1 days);
pot.join(100 ether);
}
+
function test_file() public {
hevm.warp(now + 1);
pot.drip();
- pot.file("dsr", uint(1));
+ pot.file("dsr", uint256(1));
}
+
function testFail_file() public {
hevm.warp(now + 1);
- pot.file("dsr", uint(1));
+ pot.file("dsr", uint256(1));
}
}
diff --git a/src/test/vat.t.sol b/src/test/vat.t.sol
index d59356fa..878a04ea 100644
--- a/src/test/vat.t.sol
+++ b/src/test/vat.t.sol
@@ -20,52 +20,56 @@ pragma solidity ^0.6.12;
import "ds-test/test.sol";
import "ds-token/token.sol";
-import {Vat} from '../vat.sol';
-import {Cat} from '../cat.sol';
-import {Vow} from '../vow.sol';
-import {Jug} from '../jug.sol';
-import {GemJoin, DaiJoin} from '../join.sol';
-
-import {Flipper} from './flip.t.sol';
-import {Flopper} from './flop.t.sol';
-import {Flapper} from './flap.t.sol';
+import {Vat} from "../vat.sol";
+import {Cat} from "../cat.sol";
+import {Vow} from "../vow.sol";
+import {Jug} from "../jug.sol";
+import {GemJoin, DaiJoin} from "../join.sol";
+import {Flipper} from "./flip.t.sol";
+import {Flopper} from "./flop.t.sol";
+import {Flapper} from "./flap.t.sol";
interface Hevm {
function warp(uint256) external;
- function store(address,bytes32,bytes32) external;
+ function store(address, bytes32, bytes32) external;
}
contract TestVat is Vat {
uint256 constant ONE = 10 ** 27;
- function mint(address usr, uint wad) public {
+
+ function mint(address usr, uint256 wad) public {
dai[usr] += wad * ONE;
debt += wad * ONE;
}
}
contract TestVow is Vow {
- constructor(address vat, address flapper, address flopper)
- public Vow(vat, flapper, flopper) {}
+ constructor(address vat, address flapper, address flopper) public Vow(vat, flapper, flopper) {}
+
// Total deficit
- function Awe() public view returns (uint) {
+ function Awe() public view returns (uint256) {
return vat.sin(address(this));
}
+
// Total surplus
- function Joy() public view returns (uint) {
+ function Joy() public view returns (uint256) {
return vat.dai(address(this));
}
+
// Unqueued, pre-auction debt
- function Woe() public view returns (uint) {
+ function Woe() public view returns (uint256) {
return sub(sub(Awe(), Sin), Ash);
}
}
contract Usr {
Vat public vat;
+
constructor(Vat vat_) public {
vat = vat_;
}
+
function try_call(address addr, bytes calldata data) external returns (bool) {
bytes memory _data = data;
assembly {
@@ -76,7 +80,8 @@ contract Usr {
revert(free, 32)
}
}
- function can_frob(bytes32 ilk, address u, address v, address w, int dink, int dart) public returns (bool) {
+
+ function can_frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) public returns (bool) {
string memory sig = "frob(bytes32,address,address,address,int256,int256)";
bytes memory data = abi.encodeWithSignature(sig, ilk, u, v, w, dink, dart);
@@ -86,7 +91,8 @@ contract Usr {
ok = abi.decode(success, (bool));
if (ok) return true;
}
- function can_fork(bytes32 ilk, address src, address dst, int dink, int dart) public returns (bool) {
+
+ function can_fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) public returns (bool) {
string memory sig = "fork(bytes32,address,address,int256,int256)";
bytes memory data = abi.encodeWithSignature(sig, ilk, src, dst, dink, dart);
@@ -96,33 +102,35 @@ contract Usr {
ok = abi.decode(success, (bool));
if (ok) return true;
}
- function frob(bytes32 ilk, address u, address v, address w, int dink, int dart) public {
+
+ function frob(bytes32 ilk, address u, address v, address w, int256 dink, int256 dart) public {
vat.frob(ilk, u, v, w, dink, dart);
}
- function fork(bytes32 ilk, address src, address dst, int dink, int dart) public {
+
+ function fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) public {
vat.fork(ilk, src, dst, dink, dart);
}
+
function hope(address usr) public {
vat.hope(usr);
}
}
-
contract FrobTest is DSTest {
TestVat vat;
DSToken gold;
- Jug jug;
+ Jug jug;
GemJoin gemA;
address me;
- function try_frob(bytes32 ilk, int ink, int art) public returns (bool ok) {
+ function try_frob(bytes32 ilk, int256 ink, int256 art) public returns (bool ok) {
string memory sig = "frob(bytes32,address,address,address,int256,int256)";
address self = address(this);
(ok,) = address(vat).call(abi.encodeWithSignature(sig, ilk, self, self, self, ink, art));
}
- function ray(uint wad) internal pure returns (uint) {
+ function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
@@ -135,9 +143,9 @@ contract FrobTest is DSTest {
vat.init("gold");
gemA = new GemJoin(address(vat), "gold", address(gold));
- vat.file("gold", "spot", ray(1 ether));
+ vat.file("gold", "spot", ray(1 ether));
vat.file("gold", "line", rad(1000 ether));
- vat.file("Line", rad(1000 ether));
+ vat.file("Line", rad(1000 ether));
jug = new Jug(address(vat));
jug.init("gold");
vat.rely(address(jug));
@@ -153,99 +161,110 @@ contract FrobTest is DSTest {
me = address(this);
}
- function gem(bytes32 ilk, address urn) internal view returns (uint) {
+ function gem(bytes32 ilk, address urn) internal view returns (uint256) {
return vat.gem(ilk, urn);
}
- function ink(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); art_;
+
+ function ink(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ art_;
return ink_;
}
- function art(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); ink_;
+
+ function art(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ ink_;
return art_;
}
function test_setup() public {
assertEq(gold.balanceOf(address(gemA)), 1000 ether);
- assertEq(gem("gold", address(this)), 1000 ether);
+ assertEq(gem("gold", address(this)), 1000 ether);
}
+
function test_join() public {
address urn = address(this);
gold.mint(500 ether);
- assertEq(gold.balanceOf(address(this)), 500 ether);
- assertEq(gold.balanceOf(address(gemA)), 1000 ether);
- gemA.join(urn, 500 ether);
- assertEq(gold.balanceOf(address(this)), 0 ether);
- assertEq(gold.balanceOf(address(gemA)), 1500 ether);
- gemA.exit(urn, 250 ether);
- assertEq(gold.balanceOf(address(this)), 250 ether);
- assertEq(gold.balanceOf(address(gemA)), 1250 ether);
+ assertEq(gold.balanceOf(address(this)), 500 ether);
+ assertEq(gold.balanceOf(address(gemA)), 1000 ether);
+ gemA.join(urn, 500 ether);
+ assertEq(gold.balanceOf(address(this)), 0 ether);
+ assertEq(gold.balanceOf(address(gemA)), 1500 ether);
+ gemA.exit(urn, 250 ether);
+ assertEq(gold.balanceOf(address(this)), 250 ether);
+ assertEq(gold.balanceOf(address(gemA)), 1250 ether);
}
+
function test_lock() public {
- assertEq(ink("gold", address(this)), 0 ether);
+ assertEq(ink("gold", address(this)), 0 ether);
assertEq(gem("gold", address(this)), 1000 ether);
vat.frob("gold", me, me, me, 6 ether, 0);
- assertEq(ink("gold", address(this)), 6 ether);
+ assertEq(ink("gold", address(this)), 6 ether);
assertEq(gem("gold", address(this)), 994 ether);
vat.frob("gold", me, me, me, -6 ether, 0);
- assertEq(ink("gold", address(this)), 0 ether);
+ assertEq(ink("gold", address(this)), 0 ether);
assertEq(gem("gold", address(this)), 1000 ether);
}
+
function test_calm() public {
// calm means that the debt ceiling is not exceeded
// it's ok to increase debt as long as you remain calm
- vat.file("gold", 'line', rad(10 ether));
- assertTrue( try_frob("gold", 10 ether, 9 ether));
+ vat.file("gold", "line", rad(10 ether));
+ assertTrue(try_frob("gold", 10 ether, 9 ether));
// only if under debt ceiling
- assertTrue(!try_frob("gold", 0 ether, 2 ether));
+ assertTrue(!try_frob("gold", 0 ether, 2 ether));
}
+
function test_cool() public {
// cool means that the debt has decreased
// it's ok to be over the debt ceiling as long as you're cool
- vat.file("gold", 'line', rad(10 ether));
- assertTrue(try_frob("gold", 10 ether, 8 ether));
- vat.file("gold", 'line', rad(5 ether));
+ vat.file("gold", "line", rad(10 ether));
+ assertTrue(try_frob("gold", 10 ether, 8 ether));
+ vat.file("gold", "line", rad(5 ether));
// can decrease debt when over ceiling
- assertTrue(try_frob("gold", 0 ether, -1 ether));
+ assertTrue(try_frob("gold", 0 ether, -1 ether));
}
+
function test_safe() public {
// safe means that the cdp is not risky
// you can't frob a cdp into unsafe
- vat.frob("gold", me, me, me, 10 ether, 5 ether); // safe draw
- assertTrue(!try_frob("gold", 0 ether, 6 ether)); // unsafe draw
+ vat.frob("gold", me, me, me, 10 ether, 5 ether); // safe draw
+ assertTrue(!try_frob("gold", 0 ether, 6 ether)); // unsafe draw
}
+
function test_nice() public {
// nice means that the collateral has increased or the debt has
// decreased. remaining unsafe is ok as long as you're nice
vat.frob("gold", me, me, me, 10 ether, 10 ether);
- vat.file("gold", 'spot', ray(0.5 ether)); // now unsafe
+ vat.file("gold", "spot", ray(0.5 ether)); // now unsafe
// debt can't increase if unsafe
- assertTrue(!try_frob("gold", 0 ether, 1 ether));
+ assertTrue(!try_frob("gold", 0 ether, 1 ether));
// debt can decrease
- assertTrue( try_frob("gold", 0 ether, -1 ether));
+ assertTrue(try_frob("gold", 0 ether, -1 ether));
// ink can't decrease
- assertTrue(!try_frob("gold", -1 ether, 0 ether));
+ assertTrue(!try_frob("gold", -1 ether, 0 ether));
// ink can increase
- assertTrue( try_frob("gold", 1 ether, 0 ether));
+ assertTrue(try_frob("gold", 1 ether, 0 ether));
// cdp is still unsafe
// ink can't decrease, even if debt decreases more
assertTrue(!this.try_frob("gold", -2 ether, -4 ether));
// debt can't increase, even if ink increases more
- assertTrue(!this.try_frob("gold", 5 ether, 1 ether));
+ assertTrue(!this.try_frob("gold", 5 ether, 1 ether));
// ink can decrease if end state is safe
- assertTrue( this.try_frob("gold", -1 ether, -4 ether));
- vat.file("gold", 'spot', ray(0.4 ether)); // now unsafe
+ assertTrue(this.try_frob("gold", -1 ether, -4 ether));
+ vat.file("gold", "spot", ray(0.4 ether)); // now unsafe
// debt can increase if end state is safe
- assertTrue( this.try_frob("gold", 5 ether, 1 ether));
+ assertTrue(this.try_frob("gold", 5 ether, 1 ether));
}
- function rad(uint wad) internal pure returns (uint) {
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
+
function test_alt_callers() public {
Usr ali = new Usr(vat);
Usr bob = new Usr(vat);
@@ -255,48 +274,48 @@ contract FrobTest is DSTest {
address b = address(bob);
address c = address(che);
- vat.slip("gold", a, int(rad(20 ether)));
- vat.slip("gold", b, int(rad(20 ether)));
- vat.slip("gold", c, int(rad(20 ether)));
+ vat.slip("gold", a, int256(rad(20 ether)));
+ vat.slip("gold", b, int256(rad(20 ether)));
+ vat.slip("gold", c, int256(rad(20 ether)));
ali.frob("gold", a, a, a, 10 ether, 5 ether);
// anyone can lock
- assertTrue( ali.can_frob("gold", a, a, a, 1 ether, 0 ether));
- assertTrue( bob.can_frob("gold", a, b, b, 1 ether, 0 ether));
- assertTrue( che.can_frob("gold", a, c, c, 1 ether, 0 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, 1 ether, 0 ether));
+ assertTrue(bob.can_frob("gold", a, b, b, 1 ether, 0 ether));
+ assertTrue(che.can_frob("gold", a, c, c, 1 ether, 0 ether));
// but only with their own gems
- assertTrue(!ali.can_frob("gold", a, b, a, 1 ether, 0 ether));
- assertTrue(!bob.can_frob("gold", a, c, b, 1 ether, 0 ether));
- assertTrue(!che.can_frob("gold", a, a, c, 1 ether, 0 ether));
+ assertTrue(!ali.can_frob("gold", a, b, a, 1 ether, 0 ether));
+ assertTrue(!bob.can_frob("gold", a, c, b, 1 ether, 0 ether));
+ assertTrue(!che.can_frob("gold", a, a, c, 1 ether, 0 ether));
// only the lad can free
- assertTrue( ali.can_frob("gold", a, a, a, -1 ether, 0 ether));
- assertTrue(!bob.can_frob("gold", a, b, b, -1 ether, 0 ether));
- assertTrue(!che.can_frob("gold", a, c, c, -1 ether, 0 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, -1 ether, 0 ether));
+ assertTrue(!bob.can_frob("gold", a, b, b, -1 ether, 0 ether));
+ assertTrue(!che.can_frob("gold", a, c, c, -1 ether, 0 ether));
// the lad can free to anywhere
- assertTrue( ali.can_frob("gold", a, b, a, -1 ether, 0 ether));
- assertTrue( ali.can_frob("gold", a, c, a, -1 ether, 0 ether));
+ assertTrue(ali.can_frob("gold", a, b, a, -1 ether, 0 ether));
+ assertTrue(ali.can_frob("gold", a, c, a, -1 ether, 0 ether));
// only the lad can draw
- assertTrue( ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
- assertTrue(!bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
- assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
+ assertTrue(!bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
+ assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
// the lad can draw to anywhere
- assertTrue( ali.can_frob("gold", a, a, b, 0 ether, 1 ether));
- assertTrue( ali.can_frob("gold", a, a, c, 0 ether, 1 ether));
+ assertTrue(ali.can_frob("gold", a, a, b, 0 ether, 1 ether));
+ assertTrue(ali.can_frob("gold", a, a, c, 0 ether, 1 ether));
vat.mint(address(bob), 1 ether);
vat.mint(address(che), 1 ether);
// anyone can wipe
- assertTrue( ali.can_frob("gold", a, a, a, 0 ether, -1 ether));
- assertTrue( bob.can_frob("gold", a, b, b, 0 ether, -1 ether));
- assertTrue( che.can_frob("gold", a, c, c, 0 ether, -1 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, 0 ether, -1 ether));
+ assertTrue(bob.can_frob("gold", a, b, b, 0 ether, -1 ether));
+ assertTrue(che.can_frob("gold", a, c, c, 0 ether, -1 ether));
// but only with their own dai
- assertTrue(!ali.can_frob("gold", a, a, b, 0 ether, -1 ether));
- assertTrue(!bob.can_frob("gold", a, b, c, 0 ether, -1 ether));
- assertTrue(!che.can_frob("gold", a, c, a, 0 ether, -1 ether));
+ assertTrue(!ali.can_frob("gold", a, a, b, 0 ether, -1 ether));
+ assertTrue(!bob.can_frob("gold", a, b, c, 0 ether, -1 ether));
+ assertTrue(!che.can_frob("gold", a, c, a, 0 ether, -1 ether));
}
function test_hope() public {
@@ -308,32 +327,32 @@ contract FrobTest is DSTest {
address b = address(bob);
address c = address(che);
- vat.slip("gold", a, int(rad(20 ether)));
- vat.slip("gold", b, int(rad(20 ether)));
- vat.slip("gold", c, int(rad(20 ether)));
+ vat.slip("gold", a, int256(rad(20 ether)));
+ vat.slip("gold", b, int256(rad(20 ether)));
+ vat.slip("gold", c, int256(rad(20 ether)));
ali.frob("gold", a, a, a, 10 ether, 5 ether);
// only owner can do risky actions
- assertTrue( ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
- assertTrue(!bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
- assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
+ assertTrue(!bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
+ assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
ali.hope(address(bob));
// unless they hope another user
- assertTrue( ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
- assertTrue( bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
- assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
+ assertTrue(ali.can_frob("gold", a, a, a, 0 ether, 1 ether));
+ assertTrue(bob.can_frob("gold", a, b, b, 0 ether, 1 ether));
+ assertTrue(!che.can_frob("gold", a, c, c, 0 ether, 1 ether));
}
function test_dust() public {
- assertTrue( try_frob("gold", 9 ether, 1 ether));
+ assertTrue(try_frob("gold", 9 ether, 1 ether));
vat.file("gold", "dust", rad(5 ether));
- assertTrue(!try_frob("gold", 5 ether, 2 ether));
- assertTrue( try_frob("gold", 0 ether, 5 ether));
+ assertTrue(!try_frob("gold", 5 ether, 2 ether));
+ assertTrue(try_frob("gold", 0 ether, 5 ether));
assertTrue(!try_frob("gold", 0 ether, -5 ether));
- assertTrue( try_frob("gold", 0 ether, -6 ether));
+ assertTrue(try_frob("gold", 0 ether, -6 ether));
}
}
@@ -349,63 +368,71 @@ contract JoinTest is DSTest {
vat = new TestVat();
vat.init("eth");
- gem = new DSToken("Gem");
+ gem = new DSToken("Gem");
gemA = new GemJoin(address(vat), "gem", address(gem));
vat.rely(address(gemA));
- dai = new DSToken("Dai");
+ dai = new DSToken("Dai");
daiA = new DaiJoin(address(vat), address(dai));
vat.rely(address(daiA));
dai.setOwner(address(daiA));
me = address(this);
}
+
function try_cage(address a) public payable returns (bool ok) {
string memory sig = "cage()";
(ok,) = a.call(abi.encodeWithSignature(sig));
}
- function try_join_gem(address usr, uint wad) public returns (bool ok) {
+
+ function try_join_gem(address usr, uint256 wad) public returns (bool ok) {
string memory sig = "join(address,uint256)";
(ok,) = address(gemA).call(abi.encodeWithSignature(sig, usr, wad));
}
- function try_exit_dai(address usr, uint wad) public returns (bool ok) {
+
+ function try_exit_dai(address usr, uint256 wad) public returns (bool ok) {
string memory sig = "exit(address,uint256)";
(ok,) = address(daiA).call(abi.encodeWithSignature(sig, usr, wad));
}
+
function test_gem_join() public {
gem.mint(20 ether);
gem.approve(address(gemA), 20 ether);
- assertTrue( try_join_gem(address(this), 10 ether));
+ assertTrue(try_join_gem(address(this), 10 ether));
assertEq(vat.gem("gem", me), 10 ether);
- assertTrue( try_cage(address(gemA)));
+ assertTrue(try_cage(address(gemA)));
assertTrue(!try_join_gem(address(this), 10 ether));
assertEq(vat.gem("gem", me), 10 ether);
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
+
function test_dai_exit() public {
address urn = address(this);
vat.mint(address(this), 100 ether);
vat.hope(address(daiA));
- assertTrue( try_exit_dai(urn, 40 ether));
+ assertTrue(try_exit_dai(urn, 40 ether));
assertEq(dai.balanceOf(address(this)), 40 ether);
- assertEq(vat.dai(me), rad(60 ether));
- assertTrue( try_cage(address(daiA)));
+ assertEq(vat.dai(me), rad(60 ether));
+ assertTrue(try_cage(address(daiA)));
assertTrue(!try_exit_dai(urn, 40 ether));
assertEq(dai.balanceOf(address(this)), 40 ether);
- assertEq(vat.dai(me), rad(60 ether));
+ assertEq(vat.dai(me), rad(60 ether));
}
+
function test_dai_exit_join() public {
address urn = address(this);
vat.mint(address(this), 100 ether);
vat.hope(address(daiA));
daiA.exit(urn, 60 ether);
- dai.approve(address(daiA), uint(-1));
+ dai.approve(address(daiA), uint256(-1));
daiA.join(urn, 30 ether);
- assertEq(dai.balanceOf(address(this)), 30 ether);
- assertEq(vat.dai(me), rad(70 ether));
+ assertEq(dai.balanceOf(address(this)), 30 ether);
+ assertEq(vat.dai(me), rad(70 ether));
}
+
function test_cage_no_access() public {
gemA.deny(address(this));
assertTrue(!try_cage(address(gemA)));
@@ -418,23 +445,17 @@ interface FlipLike {
struct Bid {
uint256 bid;
uint256 lot;
- address guy; // high bidder
- uint48 tic; // expiry time
- uint48 end;
+ address guy; // high bidder
+ uint48 tic; // expiry time
+ uint48 end;
address urn;
address gal;
uint256 tab;
}
- function bids(uint) external view returns (
- uint256 bid,
- uint256 lot,
- address guy,
- uint48 tic,
- uint48 end,
- address usr,
- address gal,
- uint256 tab
- );
+ function bids(uint256)
+ external
+ view
+ returns (uint256 bid, uint256 lot, address guy, uint48 tic, uint48 end, address usr, address gal, uint256 tab);
}
contract BiteTest is DSTest {
@@ -442,9 +463,9 @@ contract BiteTest is DSTest {
TestVat vat;
TestVow vow;
- Cat cat;
+ Cat cat;
DSToken gold;
- Jug jug;
+ Jug jug;
GemJoin gemA;
@@ -461,28 +482,33 @@ contract BiteTest is DSTest {
uint256 constant RAY = 10 ** 27;
uint256 constant RAD = 10 ** 45;
- function try_frob(bytes32 ilk, int ink, int art) public returns (bool ok) {
+ function try_frob(bytes32 ilk, int256 ink, int256 art) public returns (bool ok) {
string memory sig = "frob(bytes32,address,address,address,int256,int256)";
address self = address(this);
(ok,) = address(vat).call(abi.encodeWithSignature(sig, ilk, self, self, self, ink, art));
}
- function ray(uint wad) internal pure returns (uint) {
+ function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
- function gem(bytes32 ilk, address urn) internal view returns (uint) {
+ function gem(bytes32 ilk, address urn) internal view returns (uint256) {
return vat.gem(ilk, urn);
}
- function ink(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); art_;
+
+ function ink(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ art_;
return ink_;
}
- function art(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); ink_;
+
+ function art(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ ink_;
return art_;
}
@@ -490,7 +516,7 @@ contract BiteTest is DSTest {
hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
hevm.warp(604411200);
- gov = new DSToken('GOV');
+ gov = new DSToken("GOV");
gov.mint(100 ether);
vat = new TestVat();
@@ -526,7 +552,7 @@ contract BiteTest is DSTest {
vat.file("gold", "spot", ray(1 ether));
vat.file("gold", "line", rad(1000 ether));
- vat.file("Line", rad(1000 ether));
+ vat.file("Line", rad(1000 ether));
flip = new Flipper(address(vat), address(cat), "gold");
flip.rely(address(cat));
cat.rely(address(flip));
@@ -546,111 +572,114 @@ contract BiteTest is DSTest {
}
function test_set_dunk_multiple_ilks() public {
- cat.file("gold", "dunk", rad(111111 ether));
+ cat.file("gold", "dunk", rad(111111 ether));
(,, uint256 goldDunk) = cat.ilks("gold");
assertEq(goldDunk, rad(111111 ether));
cat.file("silver", "dunk", rad(222222 ether));
(,, uint256 silverDunk) = cat.ilks("silver");
assertEq(silverDunk, rad(222222 ether));
}
+
function test_cat_set_box() public {
assertEq(cat.box(), rad((10 ether) * MLN));
cat.file("box", rad((20 ether) * MLN));
assertEq(cat.box(), rad((20 ether) * MLN));
}
+
function test_bite_under_dunk() public {
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 40 ether, 100 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(2 ether)); // now unsafe
+ vat.file("gold", "spot", ray(2 ether)); // now unsafe
cat.file("gold", "dunk", rad(111 ether));
cat.file("gold", "chop", 1.1 ether);
- uint auction = cat.bite("gold", address(this));
+ uint256 auction = cat.bite("gold", address(this));
// the full CDP is liquidated
assertEq(ink("gold", address(this)), 0);
assertEq(art("gold", address(this)), 0);
// all debt goes to the vow
assertEq(vow.Awe(), rad(100 ether));
// auction is for all collateral
- (, uint lot,,,,,, uint tab) = flip.bids(auction);
- assertEq(lot, 40 ether);
- assertEq(tab, rad(110 ether));
+ (, uint256 lot,,,,,, uint256 tab) = flip.bids(auction);
+ assertEq(lot, 40 ether);
+ assertEq(tab, rad(110 ether));
}
+
function test_bite_over_dunk() public {
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 40 ether, 100 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(2 ether)); // now unsafe
+ vat.file("gold", "spot", ray(2 ether)); // now unsafe
cat.file("gold", "chop", 1.1 ether);
cat.file("gold", "dunk", rad(82.5 ether));
- uint auction = cat.bite("gold", address(this));
+ uint256 auction = cat.bite("gold", address(this));
// the CDP is partially liquidated
assertEq(ink("gold", address(this)), 10 ether);
assertEq(art("gold", address(this)), 25 ether);
// a fraction of the debt goes to the vow
assertEq(vow.Awe(), rad(75 ether));
// auction is for a fraction of the collateral
- (, uint lot,,,,,, uint tab) = FlipLike(address(flip)).bids(auction);
- assertEq(lot, 30 ether);
- assertEq(tab, rad(82.5 ether));
+ (, uint256 lot,,,,,, uint256 tab) = FlipLike(address(flip)).bids(auction);
+ assertEq(lot, 30 ether);
+ assertEq(tab, rad(82.5 ether));
}
function test_happy_bite() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 40 ether, 100 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(2 ether)); // now unsafe
+ vat.file("gold", "spot", ray(2 ether)); // now unsafe
cat.file("gold", "chop", 1.1 ether);
- assertEq(ink("gold", address(this)), 40 ether);
+ assertEq(ink("gold", address(this)), 40 ether);
assertEq(art("gold", address(this)), 100 ether);
assertEq(vow.Woe(), 0 ether);
assertEq(gem("gold", address(this)), 960 ether);
- cat.file("gold", "dunk", rad(200 ether)); // => bite everything
+ cat.file("gold", "dunk", rad(200 ether)); // => bite everything
assertEq(cat.litter(), 0);
- uint auction = cat.bite("gold", address(this));
+ uint256 auction = cat.bite("gold", address(this));
assertEq(cat.litter(), rad(110 ether));
assertEq(ink("gold", address(this)), 0);
assertEq(art("gold", address(this)), 0);
- assertEq(vow.sin(now), rad(100 ether));
+ assertEq(vow.sin(now), rad(100 ether));
assertEq(gem("gold", address(this)), 960 ether);
assertEq(vat.dai(address(vow)), rad(0 ether));
- vat.mint(address(this), 100 ether); // magic up some dai for bidding
- flip.tend(auction, 40 ether, rad(1 ether));
+ vat.mint(address(this), 100 ether); // magic up some dai for bidding
+ flip.tend(auction, 40 ether, rad(1 ether));
flip.tend(auction, 40 ether, rad(110 ether));
- assertEq(vat.dai(address(this)), rad(90 ether));
+ assertEq(vat.dai(address(this)), rad(90 ether));
assertEq(gem("gold", address(this)), 960 ether);
- flip.dent(auction, 38 ether, rad(110 ether));
- assertEq(vat.dai(address(this)), rad(90 ether));
+ flip.dent(auction, 38 ether, rad(110 ether));
+ assertEq(vat.dai(address(this)), rad(90 ether));
assertEq(gem("gold", address(this)), 962 ether);
- assertEq(vow.sin(now), rad(100 ether));
+ assertEq(vow.sin(now), rad(100 ether));
hevm.warp(now + 4 hours);
assertEq(cat.litter(), rad(110 ether));
flip.deal(auction);
assertEq(cat.litter(), 0);
- assertEq(vat.dai(address(vow)), rad(110 ether));
+ assertEq(vat.dai(address(vow)), rad(110 ether));
}
// tests a partial lot liquidation because it would fill the literbox
function test_partial_litterbox() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 100 ether);
assertEq(art("gold", address(this)), 150 ether);
@@ -661,22 +690,22 @@ contract BiteTest is DSTest {
cat.file("gold", "dunk", rad(100 ether));
assertEq(cat.box(), rad(75 ether));
assertEq(cat.litter(), 0);
- uint auction = cat.bite("gold", address(this));
+ uint256 auction = cat.bite("gold", address(this));
assertEq(ink("gold", address(this)), 50 ether);
assertEq(art("gold", address(this)), 75 ether);
assertEq(vow.sin(now), rad(75 ether));
assertEq(gem("gold", address(this)), 900 ether);
- assertEq(vat.dai(address(this)), rad(150 ether));
- assertEq(vat.dai(address(vow)), rad(0 ether));
+ assertEq(vat.dai(address(this)), rad(150 ether));
+ assertEq(vat.dai(address(vow)), rad(0 ether));
flip.tend(auction, 50 ether, rad(1 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), rad(149 ether));
flip.tend(auction, 50 ether, rad(75 ether));
assertEq(vat.dai(address(this)), rad(75 ether));
- assertEq(gem("gold", address(this)), 900 ether);
+ assertEq(gem("gold", address(this)), 900 ether);
flip.dent(auction, 25 ether, rad(75 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), rad(75 ether));
@@ -686,20 +715,20 @@ contract BiteTest is DSTest {
hevm.warp(now + 4 hours);
flip.deal(auction);
assertEq(cat.litter(), 0);
- assertEq(gem("gold", address(this)), 950 ether);
- assertEq(vat.dai(address(this)), rad(75 ether));
- assertEq(vat.dai(address(vow)), rad(75 ether));
+ assertEq(gem("gold", address(this)), 950 ether);
+ assertEq(vat.dai(address(this)), rad(75 ether));
+ assertEq(vat.dai(address(vow)), rad(75 ether));
}
// tests a partial lot liquidation because it would fill the literbox
function test_partial_litterbox_realistic_values() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
cat.file("gold", "chop", 1.13 ether);
assertEq(ink("gold", address(this)), 100 ether);
@@ -714,37 +743,37 @@ contract BiteTest is DSTest {
jug.file("gold", "duty", EIGHT_PCT);
hevm.warp(now + 10 days);
jug.drip("gold");
- (, uint rate,,,) = vat.ilks("gold");
+ (, uint256 rate,,,) = vat.ilks("gold");
- uint vowBalance = vat.dai(address(vow)); // Balance updates after vat.fold is called from jug
+ uint256 vowBalance = vat.dai(address(vow)); // Balance updates after vat.fold is called from jug
cat.file("box", rad(75 ether));
cat.file("gold", "dunk", rad(100 ether));
assertEq(cat.box(), rad(75 ether));
assertEq(cat.litter(), 0);
- uint auction = cat.bite("gold", address(this));
- (,,,,,,,uint tab) = flip.bids(auction);
+ uint256 auction = cat.bite("gold", address(this));
+ (,,,,,,, uint256 tab) = flip.bids(auction);
assertTrue(cat.box() - cat.litter() < ray(1 ether)); // Rounding error to fill box
- assertEq(cat.litter(), tab); // tab = 74.9999... RAD
+ assertEq(cat.litter(), tab); // tab = 74.9999... RAD
uint256 dart = rad(75 ether) * WAD / rate / 1.13 ether; // room / rate / chop
uint256 dink = 100 ether * dart / 150 ether;
assertEq(ink("gold", address(this)), 100 ether - dink); // Taken in vat.grab
assertEq(art("gold", address(this)), 150 ether - dart); // Taken in vat.grab
- assertEq(vow.sin(now), dart * rate);
+ assertEq(vow.sin(now), dart * rate);
assertEq(gem("gold", address(this)), 900 ether);
assertEq(vat.dai(address(this)), rad(150 ether));
- assertEq(vat.dai(address(vow)), vowBalance);
- flip.tend(auction, dink, rad( 1 ether));
+ assertEq(vat.dai(address(vow)), vowBalance);
+ flip.tend(auction, dink, rad(1 ether));
assertEq(cat.litter(), tab);
assertEq(vat.dai(address(this)), rad(149 ether));
flip.tend(auction, dink, tab);
assertEq(vat.dai(address(this)), rad(150 ether) - tab);
- assertEq(gem("gold", address(this)), 900 ether);
+ assertEq(gem("gold", address(this)), 900 ether);
flip.dent(auction, 25 ether, tab);
assertEq(cat.litter(), tab);
assertEq(vat.dai(address(this)), rad(150 ether) - tab);
@@ -754,20 +783,20 @@ contract BiteTest is DSTest {
hevm.warp(now + 4 hours);
flip.deal(auction);
assertEq(cat.litter(), 0);
- assertEq(gem("gold", address(this)), 900 ether + dink); // (flux another 25 wad into gem)
- assertEq(vat.dai(address(this)), rad(150 ether) - tab);
- assertEq(vat.dai(address(vow)), vowBalance + tab);
+ assertEq(gem("gold", address(this)), 900 ether + dink); // (flux another 25 wad into gem)
+ assertEq(vat.dai(address(this)), rad(150 ether) - tab);
+ assertEq(vat.dai(address(vow)), vowBalance + tab);
}
// tests a partial lot liquidation that fill litterbox
function testFail_fill_litterbox() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 100 ether);
assertEq(art("gold", address(this)), 150 ether);
@@ -793,18 +822,18 @@ contract BiteTest is DSTest {
function testFail_dusty_litterbox() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 50 ether, 80 ether + 1);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 50 ether);
assertEq(art("gold", address(this)), 80 ether + 1);
assertEq(vow.Woe(), 0 ether);
assertEq(gem("gold", address(this)), 950 ether);
- cat.file("box", rad(100 ether));
+ cat.file("box", rad(100 ether));
vat.file("gold", "dust", rad(20 ether));
cat.file("gold", "dunk", rad(100 ether));
@@ -819,11 +848,11 @@ contract BiteTest is DSTest {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 100 ether);
assertEq(art("gold", address(this)), 150 ether);
@@ -840,11 +869,11 @@ contract BiteTest is DSTest {
function test_partial_litterbox_multiple_bites() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
// tag=4, mat=2
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 100 ether);
assertEq(art("gold", address(this)), 150 ether);
@@ -855,7 +884,7 @@ contract BiteTest is DSTest {
cat.file("gold", "dunk", rad(100 ether));
assertEq(cat.box(), rad(75 ether));
assertEq(cat.litter(), 0);
- uint auction = cat.bite("gold", address(this));
+ uint256 auction = cat.bite("gold", address(this));
assertEq(cat.litter(), rad(75 ether));
assertEq(ink("gold", address(this)), 50 ether);
assertEq(art("gold", address(this)), 75 ether);
@@ -863,14 +892,14 @@ contract BiteTest is DSTest {
assertEq(gem("gold", address(this)), 900 ether);
assertEq(vat.dai(address(this)), rad(150 ether));
- assertEq(vat.dai(address(vow)), rad(0 ether));
- flip.tend(auction, 50 ether, rad( 1 ether));
+ assertEq(vat.dai(address(vow)), rad(0 ether));
+ flip.tend(auction, 50 ether, rad(1 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), rad(149 ether));
flip.tend(auction, 50 ether, rad(75 ether));
assertEq(vat.dai(address(this)), rad(75 ether));
- assertEq(gem("gold", address(this)), 900 ether);
+ assertEq(gem("gold", address(this)), 900 ether);
flip.dent(auction, 25 ether, rad(75 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), rad(75 ether));
@@ -885,8 +914,8 @@ contract BiteTest is DSTest {
flip.deal(auction);
assertEq(cat.litter(), 0);
assertEq(gem("gold", address(this)), 950 ether);
- assertEq(vat.dai(address(this)), rad(75 ether));
- assertEq(vat.dai(address(vow)), rad(75 ether));
+ assertEq(vat.dai(address(this)), rad(75 ether));
+ assertEq(vat.dai(address(vow)), rad(75 ether));
// now bite more
auction = cat.bite("gold", address(this));
@@ -897,14 +926,14 @@ contract BiteTest is DSTest {
assertEq(gem("gold", address(this)), 950 ether);
assertEq(vat.dai(address(this)), rad(75 ether));
- assertEq(vat.dai(address(vow)), rad(75 ether));
- flip.tend(auction, 50 ether, rad( 1 ether));
+ assertEq(vat.dai(address(vow)), rad(75 ether));
+ flip.tend(auction, 50 ether, rad(1 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), rad(74 ether));
flip.tend(auction, 50 ether, rad(75 ether));
assertEq(vat.dai(address(this)), 0);
- assertEq(gem("gold", address(this)), 950 ether);
+ assertEq(gem("gold", address(this)), 950 ether);
flip.dent(auction, 25 ether, rad(75 ether));
assertEq(cat.litter(), rad(75 ether));
assertEq(vat.dai(address(this)), 0);
@@ -914,20 +943,20 @@ contract BiteTest is DSTest {
hevm.warp(now + 4 hours);
flip.deal(auction);
assertEq(cat.litter(), 0);
- assertEq(gem("gold", address(this)), 1000 ether);
+ assertEq(gem("gold", address(this)), 1000 ether);
assertEq(vat.dai(address(this)), 0);
- assertEq(vat.dai(address(vow)), rad(150 ether));
+ assertEq(vat.dai(address(vow)), rad(150 ether));
}
function testFail_null_auctions_dart_realistic_values() public {
vat.file("gold", "dust", rad(100 ether));
vat.file("gold", "spot", ray(2.5 ether));
vat.file("gold", "line", rad(2000 ether));
- vat.file("Line", rad(2000 ether));
+ vat.file("Line", rad(2000 ether));
vat.fold("gold", address(vow), int256(ray(0.25 ether)));
vat.frob("gold", me, me, me, 800 ether, 2000 ether);
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
// slightly contrived value to leave tiny amount of room post-liquidation
cat.file("box", rad(1130 ether) + 1);
@@ -935,7 +964,7 @@ contract BiteTest is DSTest {
cat.file("gold", "chop", 1.13 ether);
cat.bite("gold", me);
assertEq(cat.litter(), rad(1130 ether));
- uint room = cat.box() - cat.litter();
+ uint256 room = cat.box() - cat.litter();
assertEq(room, 1);
(, uint256 rate,,,) = vat.ilks("gold");
(, uint256 chop,) = cat.ilks("gold");
@@ -953,15 +982,15 @@ contract BiteTest is DSTest {
vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 200 ether);
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
// contrived value to leave tiny amount of room post-liquidation
cat.file("box", rad(113 ether) + 2);
- cat.file("gold", "dunk", rad(113 ether));
+ cat.file("gold", "dunk", rad(113 ether));
cat.file("gold", "chop", 1.13 ether);
cat.bite("gold", me);
assertEq(cat.litter(), rad(113 ether));
- uint room = cat.box() - cat.litter();
+ uint256 room = cat.box() - cat.litter();
assertEq(room, 2);
(, uint256 rate,,,) = vat.ilks("gold");
(, uint256 chop,) = cat.ilks("gold");
@@ -980,7 +1009,7 @@ contract BiteTest is DSTest {
cat.file("gold", "dunk", rad(50 ether));
vat.frob("gold", me, me, me, 1, 100 ether);
- vat.file("gold", 'spot', 1); // massive price crash, now unsafe
+ vat.file("gold", "spot", 1); // massive price crash, now unsafe
// This should leave us with 0 dink value, and fail
cat.bite("gold", me);
@@ -989,15 +1018,15 @@ contract BiteTest is DSTest {
function testFail_null_auctions_dink_artificial_values_2() public {
vat.file("gold", "spot", ray(2000 ether));
vat.file("gold", "line", rad(20000 ether));
- vat.file("Line", rad(20000 ether));
+ vat.file("Line", rad(20000 ether));
vat.frob("gold", me, me, me, 10 ether, 15000 ether);
- cat.file("box", rad(1000000 ether)); // plenty of room
+ cat.file("box", rad(1000000 ether)); // plenty of room
// misconfigured dunk (e.g. precision factor incorrect in spell)
cat.file("gold", "dunk", rad(100));
- vat.file("gold", 'spot', ray(1000 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1000 ether)); // now unsafe
// This should leave us with 0 dink value, and fail
cat.bite("gold", me);
@@ -1006,10 +1035,10 @@ contract BiteTest is DSTest {
function testFail_null_spot_value() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
- vat.file("gold", 'spot', ray(1 ether)); // now unsafe
+ vat.file("gold", "spot", ray(1 ether)); // now unsafe
assertEq(ink("gold", address(this)), 100 ether);
assertEq(art("gold", address(this)), 150 ether);
@@ -1025,7 +1054,7 @@ contract BiteTest is DSTest {
assertEq(vow.sin(now), rad(75 ether));
assertEq(gem("gold", address(this)), 900 ether);
- vat.file("gold", 'spot', 0);
+ vat.file("gold", "spot", 0);
// this should fail because spot is 0
cat.bite("gold", address(this));
@@ -1034,7 +1063,7 @@ contract BiteTest is DSTest {
function testFail_vault_is_safe() public {
// spot = tag / (par . mat)
// tag=5, mat=2
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 100 ether, 150 ether);
assertEq(ink("gold", address(this)), 100 ether);
@@ -1050,34 +1079,34 @@ contract BiteTest is DSTest {
}
function test_floppy_bite() public {
- vat.file("gold", 'spot', ray(2.5 ether));
+ vat.file("gold", "spot", ray(2.5 ether));
vat.frob("gold", me, me, me, 40 ether, 100 ether);
- vat.file("gold", 'spot', ray(2 ether)); // now unsafe
+ vat.file("gold", "spot", ray(2 ether)); // now unsafe
- cat.file("gold", "dunk", rad(200 ether)); // => bite everything
- assertEq(vow.sin(now), rad( 0 ether));
+ cat.file("gold", "dunk", rad(200 ether)); // => bite everything
+ assertEq(vow.sin(now), rad(0 ether));
cat.bite("gold", address(this));
assertEq(vow.sin(now), rad(100 ether));
assertEq(vow.Sin(), rad(100 ether));
vow.flog(now);
- assertEq(vow.Sin(), rad( 0 ether));
+ assertEq(vow.Sin(), rad(0 ether));
assertEq(vow.Woe(), rad(100 ether));
- assertEq(vow.Joy(), rad( 0 ether));
- assertEq(vow.Ash(), rad( 0 ether));
+ assertEq(vow.Joy(), rad(0 ether));
+ assertEq(vow.Ash(), rad(0 ether));
vow.file("sump", rad(10 ether));
vow.file("dump", 2000 ether);
- uint f1 = vow.flop();
- assertEq(vow.Woe(), rad(90 ether));
- assertEq(vow.Joy(), rad( 0 ether));
- assertEq(vow.Ash(), rad(10 ether));
+ uint256 f1 = vow.flop();
+ assertEq(vow.Woe(), rad(90 ether));
+ assertEq(vow.Joy(), rad(0 ether));
+ assertEq(vow.Ash(), rad(10 ether));
flop.dent(f1, 1000 ether, rad(10 ether));
- assertEq(vow.Woe(), rad(90 ether));
- assertEq(vow.Joy(), rad( 0 ether));
- assertEq(vow.Ash(), rad( 0 ether));
+ assertEq(vow.Woe(), rad(90 ether));
+ assertEq(vow.Joy(), rad(0 ether));
+ assertEq(vow.Ash(), rad(0 ether));
- assertEq(gov.balanceOf(address(this)), 100 ether);
+ assertEq(gov.balanceOf(address(this)), 100 ether);
hevm.warp(now + 4 hours);
gov.setOwner(address(flop));
flop.deal(f1);
@@ -1087,41 +1116,49 @@ contract BiteTest is DSTest {
function test_flappy_bite() public {
// get some surplus
vat.mint(address(vow), 100 ether);
- assertEq(vat.dai(address(vow)), rad(100 ether));
+ assertEq(vat.dai(address(vow)), rad(100 ether));
assertEq(gov.balanceOf(address(this)), 100 ether);
vow.file("bump", rad(100 ether));
assertEq(vow.Awe(), 0 ether);
- uint id = vow.flap();
+ uint256 id = vow.flap();
- assertEq(vat.dai(address(this)), rad(0 ether));
+ assertEq(vat.dai(address(this)), rad(0 ether));
assertEq(gov.balanceOf(address(this)), 100 ether);
flap.tend(id, rad(100 ether), 10 ether);
hevm.warp(now + 4 hours);
gov.setOwner(address(flap));
flap.deal(id);
- assertEq(vat.dai(address(this)), rad(100 ether));
- assertEq(gov.balanceOf(address(this)), 90 ether);
+ assertEq(vat.dai(address(this)), rad(100 ether));
+ assertEq(gov.balanceOf(address(this)), 90 ether);
}
}
contract FoldTest is DSTest {
Vat vat;
- function ray(uint wad) internal pure returns (uint) {
+ function ray(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 9;
}
- function rad(uint wad) internal pure returns (uint) {
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * 10 ** 27;
}
- function tab(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); ink_;
- (uint Art_, uint rate, uint spot, uint line, uint dust) = vat.ilks(ilk);
- Art_; spot; line; dust;
+
+ function tab(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ ink_;
+ (uint256 Art_, uint256 rate, uint256 spot, uint256 line, uint256 dust) = vat.ilks(ilk);
+ Art_;
+ spot;
+ line;
+ dust;
return art_ * rate;
}
- function jam(bytes32 ilk, address urn) internal view returns (uint) {
- (uint ink_, uint art_) = vat.urns(ilk, urn); art_;
+
+ function jam(bytes32 ilk, address urn) internal view returns (uint256) {
+ (uint256 ink_, uint256 art_) = vat.urns(ilk, urn);
+ art_;
return ink_;
}
@@ -1131,22 +1168,24 @@ contract FoldTest is DSTest {
vat.file("Line", rad(100 ether));
vat.file("gold", "line", rad(100 ether));
}
- function draw(bytes32 ilk, uint dai) internal {
+
+ function draw(bytes32 ilk, uint256 dai) internal {
vat.file("Line", rad(dai));
vat.file(ilk, "line", rad(dai));
vat.file(ilk, "spot", 10 ** 27 * 10000 ether);
address self = address(this);
- vat.slip(ilk, self, 10 ** 27 * 1 ether);
- vat.frob(ilk, self, self, self, int(1 ether), int(dai));
+ vat.slip(ilk, self, 10 ** 27 * 1 ether);
+ vat.frob(ilk, self, self, self, int256(1 ether), int256(dai));
}
+
function test_fold() public {
address self = address(this);
- address ali = address(bytes20("ali"));
+ address ali = address(bytes20("ali"));
draw("gold", 1 ether);
- assertEq(tab("gold", self), rad(1.00 ether));
- vat.fold("gold", ali, int(ray(0.05 ether)));
+ assertEq(tab("gold", self), rad(1.0 ether));
+ vat.fold("gold", ali, int256(ray(0.05 ether)));
assertEq(tab("gold", self), rad(1.05 ether));
- assertEq(vat.dai(ali), rad(0.05 ether));
+ assertEq(vat.dai(ali), rad(0.05 ether));
}
}
diff --git a/src/test/vow.t.sol b/src/test/vow.t.sol
index b88027d0..6b108efa 100644
--- a/src/test/vow.t.sol
+++ b/src/test/vow.t.sol
@@ -19,18 +19,19 @@ pragma solidity ^0.6.12;
import "ds-test/test.sol";
-import {Flopper as Flop} from './flop.t.sol';
-import {Flapper as Flap} from './flap.t.sol';
-import {TestVat as Vat} from './vat.t.sol';
-import {Vow} from '../vow.sol';
+import {Flopper as Flop} from "./flop.t.sol";
+import {Flapper as Flap} from "./flap.t.sol";
+import {TestVat as Vat} from "./vat.t.sol";
+import {Vow} from "../vow.sol";
interface Hevm {
function warp(uint256) external;
}
contract Gem {
- mapping (address => uint256) public balanceOf;
- function mint(address usr, uint rad) public {
+ mapping(address => uint256) public balanceOf;
+
+ function mint(address usr, uint256 rad) public {
balanceOf[usr] += rad;
}
}
@@ -38,11 +39,11 @@ contract Gem {
contract VowTest is DSTest {
Hevm hevm;
- Vat vat;
- Vow vow;
+ Vat vat;
+ Vow vow;
Flop flop;
Flap flap;
- Gem gov;
+ Gem gov;
function setUp() public {
hevm = Hevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
@@ -50,7 +51,7 @@ contract VowTest is DSTest {
vat = new Vat();
- gov = new Gem();
+ gov = new Gem();
flop = new Flop(address(vat), address(gov));
flap = new Flap(address(vat), address(gov));
@@ -66,14 +67,16 @@ contract VowTest is DSTest {
vat.hope(address(flop));
}
- function try_flog(uint era) internal returns (bool ok) {
+ function try_flog(uint256 era) internal returns (bool ok) {
string memory sig = "flog(uint256)";
(ok,) = address(vow).call(abi.encodeWithSignature(sig, era));
}
- function try_dent(uint id, uint lot, uint bid) internal returns (bool ok) {
+
+ function try_dent(uint256 id, uint256 lot, uint256 bid) internal returns (bool ok) {
string memory sig = "dent(uint256,uint256,uint256)";
(ok,) = address(flop).call(abi.encodeWithSignature(sig, id, lot, bid));
}
+
function try_call(address addr, bytes calldata data) external returns (bool) {
bytes memory _data = data;
assembly {
@@ -84,6 +87,7 @@ contract VowTest is DSTest {
revert(free, 32)
}
}
+
function can_flap() public returns (bool) {
string memory sig = "flap()";
bytes memory data = abi.encodeWithSignature(sig);
@@ -94,6 +98,7 @@ contract VowTest is DSTest {
ok = abi.decode(success, (bool));
if (ok) return true;
}
+
function can_flop() public returns (bool) {
string memory sig = "flop()";
bytes memory data = abi.encodeWithSignature(sig);
@@ -105,21 +110,24 @@ contract VowTest is DSTest {
if (ok) return true;
}
- uint constant ONE = 10 ** 27;
- function rad(uint wad) internal pure returns (uint) {
+ uint256 constant ONE = 10 ** 27;
+
+ function rad(uint256 wad) internal pure returns (uint256) {
return wad * ONE;
}
- function suck(address who, uint wad) internal {
+ function suck(address who, uint256 wad) internal {
vow.fess(rad(wad));
- vat.init('');
+ vat.init("");
vat.suck(address(vow), who, rad(wad));
}
- function flog(uint wad) internal {
- suck(address(0), wad); // suck dai into the zero address
+
+ function flog(uint256 wad) internal {
+ suck(address(0), wad); // suck dai into the zero address
vow.flog(now);
}
- function heal(uint wad) internal {
+
+ function heal(uint256 wad) internal {
vow.heal(rad(wad));
}
@@ -133,8 +141,8 @@ contract VowTest is DSTest {
assertEq(vat.can(address(vow), address(flap)), 1);
assertEq(vat.can(address(vow), address(newFlap)), 0);
- vow.file('flapper', address(newFlap));
- vow.file('flopper', address(newFlop));
+ vow.file("flapper", address(newFlap));
+ vow.file("flopper", address(newFlop));
assertEq(address(vow.flapper()), address(newFlap));
assertEq(address(vow.flopper()), address(newFlop));
@@ -145,37 +153,37 @@ contract VowTest is DSTest {
function test_flog_wait() public {
assertEq(vow.wait(), 0);
- vow.file('wait', uint(100 seconds));
+ vow.file("wait", uint256(100 seconds));
assertEq(vow.wait(), 100 seconds);
- uint tic = now;
- vow.fess(100 ether);
- hevm.warp(tic + 99 seconds);
- assertTrue(!try_flog(tic) );
- hevm.warp(tic + 100 seconds);
- assertTrue( try_flog(tic) );
+ uint256 tic = now;
+ vow.fess(100 ether);
+ hevm.warp(tic + 99 seconds);
+ assertTrue(!try_flog(tic));
+ hevm.warp(tic + 100 seconds);
+ assertTrue(try_flog(tic));
}
function test_no_reflop() public {
flog(100 ether);
- assertTrue( can_flop() );
+ assertTrue(can_flop());
vow.flop();
- assertTrue(!can_flop() );
+ assertTrue(!can_flop());
}
function test_no_flop_pending_joy() public {
flog(200 ether);
vat.mint(address(vow), 100 ether);
- assertTrue(!can_flop() );
+ assertTrue(!can_flop());
heal(100 ether);
- assertTrue( can_flop() );
+ assertTrue(can_flop());
}
function test_flap() public {
vat.mint(address(vow), 100 ether);
- assertTrue( can_flap() );
+ assertTrue(can_flap());
}
function test_no_flap_pending_sin() public {
@@ -183,50 +191,53 @@ contract VowTest is DSTest {
flog(100 ether);
vat.mint(address(vow), 50 ether);
- assertTrue(!can_flap() );
+ assertTrue(!can_flap());
}
+
function test_no_flap_nonzero_woe() public {
vow.file("bump", uint256(0 ether));
flog(100 ether);
vat.mint(address(vow), 50 ether);
- assertTrue(!can_flap() );
+ assertTrue(!can_flap());
}
+
function test_no_flap_pending_flop() public {
flog(100 ether);
vow.flop();
vat.mint(address(vow), 100 ether);
- assertTrue(!can_flap() );
+ assertTrue(!can_flap());
}
+
function test_no_flap_pending_heal() public {
flog(100 ether);
- uint id = vow.flop();
+ uint256 id = vow.flop();
vat.mint(address(this), 100 ether);
flop.dent(id, 0 ether, rad(100 ether));
- assertTrue(!can_flap() );
+ assertTrue(!can_flap());
}
function test_no_surplus_after_good_flop() public {
flog(100 ether);
- uint id = vow.flop();
+ uint256 id = vow.flop();
vat.mint(address(this), 100 ether);
- flop.dent(id, 0 ether, rad(100 ether)); // flop succeeds..
+ flop.dent(id, 0 ether, rad(100 ether)); // flop succeeds..
- assertTrue(!can_flap() );
+ assertTrue(!can_flap());
}
function test_multiple_flop_dents() public {
flog(100 ether);
- uint id = vow.flop();
+ uint256 id = vow.flop();
vat.mint(address(this), 100 ether);
- assertTrue(try_dent(id, 2 ether, rad(100 ether)));
+ assertTrue(try_dent(id, 2 ether, rad(100 ether)));
vat.mint(address(this), 100 ether);
- assertTrue(try_dent(id, 1 ether, rad(100 ether)));
+ assertTrue(try_dent(id, 1 ether, rad(100 ether)));
}
}
diff --git a/src/vat.sol b/src/vat.sol
index ff90bbed..12164cb6 100644
--- a/src/vat.sol
+++ b/src/vat.sol
@@ -25,44 +25,60 @@ pragma solidity ^0.6.12;
contract Vat {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address usr) external auth { require(live == 1, "Vat/not-live"); wards[usr] = 1; }
- function deny(address usr) external auth { require(live == 1, "Vat/not-live"); wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ require(live == 1, "Vat/not-live");
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ require(live == 1, "Vat/not-live");
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Vat/not-authorized");
_;
}
- mapping(address => mapping (address => uint)) public can;
- function hope(address usr) external { can[msg.sender][usr] = 1; }
- function nope(address usr) external { can[msg.sender][usr] = 0; }
+ mapping(address => mapping(address => uint256)) public can;
+
+ function hope(address usr) external {
+ can[msg.sender][usr] = 1;
+ }
+
+ function nope(address usr) external {
+ can[msg.sender][usr] = 0;
+ }
+
function wish(address bit, address usr) internal view returns (bool) {
return either(bit == usr, can[bit][usr] == 1);
}
// --- Data ---
struct Ilk {
- uint256 Art; // Total Normalised Debt [wad]
- uint256 rate; // Accumulated Rates [ray]
- uint256 spot; // Price with Safety Margin [ray]
- uint256 line; // Debt Ceiling [rad]
- uint256 dust; // Urn Debt Floor [rad]
+ uint256 Art; // Total Normalised Debt [wad]
+ uint256 rate; // Accumulated Rates [ray]
+ uint256 spot; // Price with Safety Margin [ray]
+ uint256 line; // Debt Ceiling [rad]
+ uint256 dust; // Urn Debt Floor [rad]
}
+
struct Urn {
- uint256 ink; // Locked Collateral [wad]
- uint256 art; // Normalised Debt [wad]
+ uint256 ink; // Locked Collateral [wad]
+ uint256 art; // Normalised Debt [wad]
}
- mapping (bytes32 => Ilk) public ilks;
- mapping (bytes32 => mapping (address => Urn )) public urns;
- mapping (bytes32 => mapping (address => uint)) public gem; // [wad]
- mapping (address => uint256) public dai; // [rad]
- mapping (address => uint256) public sin; // [rad]
+ mapping(bytes32 => Ilk) public ilks;
+ mapping(bytes32 => mapping(address => Urn)) public urns;
+ mapping(bytes32 => mapping(address => uint256)) public gem; // [wad]
+ mapping(address => uint256) public dai; // [rad]
+ mapping(address => uint256) public sin; // [rad]
- uint256 public debt; // Total Dai Issued [rad]
- uint256 public vice; // Total Unbacked Dai [rad]
- uint256 public Line; // Total Debt Ceiling [rad]
- uint256 public live; // Active Flag
+ uint256 public debt; // Total Dai Issued [rad]
+ uint256 public vice; // Total Unbacked Dai [rad]
+ uint256 public Line; // Total Debt Ceiling [rad]
+ uint256 public live; // Active Flag
// --- Init ---
constructor() public {
@@ -71,28 +87,33 @@ contract Vat {
}
// --- Math ---
- function _add(uint x, int y) internal pure returns (uint z) {
- z = x + uint(y);
+ function _add(uint256 x, int256 y) internal pure returns (uint256 z) {
+ z = x + uint256(y);
require(y >= 0 || z <= x);
require(y <= 0 || z >= x);
}
- function _sub(uint x, int y) internal pure returns (uint z) {
- z = x - uint(y);
+
+ function _sub(uint256 x, int256 y) internal pure returns (uint256 z) {
+ z = x - uint256(y);
require(y <= 0 || z <= x);
require(y >= 0 || z >= x);
}
- function _mul(uint x, int y) internal pure returns (int z) {
- z = int(x) * y;
- require(int(x) >= 0);
- require(y == 0 || z / y == int(x));
+
+ function _mul(uint256 x, int256 y) internal pure returns (int256 z) {
+ z = int256(x) * y;
+ require(int256(x) >= 0);
+ require(y == 0 || z / y == int256(x));
}
- function _add(uint x, uint y) internal pure returns (uint z) {
+
+ function _add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
- function _sub(uint x, uint y) internal pure returns (uint z) {
+
+ function _sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
- function _mul(uint x, uint y) internal pure returns (uint z) {
+
+ function _mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
@@ -101,18 +122,21 @@ contract Vat {
require(ilks[ilk].rate == 0, "Vat/ilk-already-init");
ilks[ilk].rate = 10 ** 27;
}
- function file(bytes32 what, uint data) external auth {
+
+ function file(bytes32 what, uint256 data) external auth {
require(live == 1, "Vat/not-live");
if (what == "Line") Line = data;
else revert("Vat/file-unrecognized-param");
}
- function file(bytes32 ilk, bytes32 what, uint data) external auth {
+
+ function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
require(live == 1, "Vat/not-live");
if (what == "spot") ilks[ilk].spot = data;
else if (what == "line") ilks[ilk].line = data;
else if (what == "dust") ilks[ilk].dust = data;
else revert("Vat/file-unrecognized-param");
}
+
function cage() external auth {
live = 0;
}
@@ -121,11 +145,13 @@ contract Vat {
function slip(bytes32 ilk, address usr, int256 wad) external auth {
gem[ilk][usr] = _add(gem[ilk][usr], wad);
}
+
function flux(bytes32 ilk, address src, address dst, uint256 wad) external {
require(wish(src, msg.sender), "Vat/not-allowed");
gem[ilk][src] = _sub(gem[ilk][src], wad);
gem[ilk][dst] = _add(gem[ilk][dst], wad);
}
+
function move(address src, address dst, uint256 rad) external {
require(wish(src, msg.sender), "Vat/not-allowed");
dai[src] = _sub(dai[src], rad);
@@ -133,14 +159,15 @@ contract Vat {
}
function either(bool x, bool y) internal pure returns (bool z) {
- assembly{ z := or(x, y)}
+ assembly { z := or(x, y) }
}
+
function both(bool x, bool y) internal pure returns (bool z) {
- assembly{ z := and(x, y)}
+ assembly { z := and(x, y) }
}
// --- CDP Manipulation ---
- function frob(bytes32 i, address u, address v, address w, int dink, int dart) external {
+ function frob(bytes32 i, address u, address v, address w, int256 dink, int256 dart) external {
// system is live
require(live == 1, "Vat/not-live");
@@ -153,9 +180,9 @@ contract Vat {
urn.art = _add(urn.art, dart);
ilk.Art = _add(ilk.Art, dart);
- int dtab = _mul(ilk.rate, dart);
- uint tab = _mul(ilk.rate, urn.art);
- debt = _add(debt, dtab);
+ int256 dtab = _mul(ilk.rate, dart);
+ uint256 tab = _mul(ilk.rate, urn.art);
+ debt = _add(debt, dtab);
// either debt has decreased, or debt ceilings are not exceeded
require(either(dart <= 0, both(_mul(ilk.Art, ilk.rate) <= ilk.line, debt <= Line)), "Vat/ceiling-exceeded");
@@ -173,13 +200,14 @@ contract Vat {
require(either(urn.art == 0, tab >= ilk.dust), "Vat/dust");
gem[i][v] = _sub(gem[i][v], dink);
- dai[w] = _add(dai[w], dtab);
+ dai[w] = _add(dai[w], dtab);
urns[i][u] = urn;
- ilks[i] = ilk;
+ ilks[i] = ilk;
}
+
// --- CDP Fungibility ---
- function fork(bytes32 ilk, address src, address dst, int dink, int dart) external {
+ function fork(bytes32 ilk, address src, address dst, int256 dink, int256 dart) external {
Urn storage u = urns[ilk][src];
Urn storage v = urns[ilk][dst];
Ilk storage i = ilks[ilk];
@@ -189,8 +217,8 @@ contract Vat {
v.ink = _add(v.ink, dink);
v.art = _add(v.art, dart);
- uint utab = _mul(u.art, i.rate);
- uint vtab = _mul(v.art, i.rate);
+ uint256 utab = _mul(u.art, i.rate);
+ uint256 vtab = _mul(v.art, i.rate);
// both sides consent
require(both(wish(src, msg.sender), wish(dst, msg.sender)), "Vat/not-allowed");
@@ -203,8 +231,9 @@ contract Vat {
require(either(utab >= i.dust, u.art == 0), "Vat/dust-src");
require(either(vtab >= i.dust, v.art == 0), "Vat/dust-dst");
}
+
// --- CDP Confiscation ---
- function grab(bytes32 i, address u, address v, address w, int dink, int dart) external auth {
+ function grab(bytes32 i, address u, address v, address w, int256 dink, int256 dart) external auth {
Urn storage urn = urns[i][u];
Ilk storage ilk = ilks[i];
@@ -212,35 +241,36 @@ contract Vat {
urn.art = _add(urn.art, dart);
ilk.Art = _add(ilk.Art, dart);
- int dtab = _mul(ilk.rate, dart);
+ int256 dtab = _mul(ilk.rate, dart);
gem[i][v] = _sub(gem[i][v], dink);
- sin[w] = _sub(sin[w], dtab);
- vice = _sub(vice, dtab);
+ sin[w] = _sub(sin[w], dtab);
+ vice = _sub(vice, dtab);
}
// --- Settlement ---
- function heal(uint rad) external {
+ function heal(uint256 rad) external {
address u = msg.sender;
sin[u] = _sub(sin[u], rad);
dai[u] = _sub(dai[u], rad);
- vice = _sub(vice, rad);
- debt = _sub(debt, rad);
+ vice = _sub(vice, rad);
+ debt = _sub(debt, rad);
}
- function suck(address u, address v, uint rad) external auth {
+
+ function suck(address u, address v, uint256 rad) external auth {
sin[u] = _add(sin[u], rad);
dai[v] = _add(dai[v], rad);
- vice = _add(vice, rad);
- debt = _add(debt, rad);
+ vice = _add(vice, rad);
+ debt = _add(debt, rad);
}
// --- Rates ---
- function fold(bytes32 i, address u, int rate) external auth {
+ function fold(bytes32 i, address u, int256 rate) external auth {
require(live == 1, "Vat/not-live");
Ilk storage ilk = ilks[i];
ilk.rate = _add(ilk.rate, rate);
- int rad = _mul(ilk.Art, rate);
- dai[u] = _add(dai[u], rad);
- debt = _add(debt, rad);
+ int256 rad = _mul(ilk.Art, rate);
+ dai[u] = _add(dai[u], rad);
+ debt = _add(debt, rad);
}
}
diff --git a/src/vow.sol b/src/vow.sol
index f28d6997..bd497653 100644
--- a/src/vow.sol
+++ b/src/vow.sol
@@ -24,20 +24,20 @@ pragma solidity ^0.6.12;
// New deployments of this contract will need to include custom events (TO DO).
interface FlopLike {
- function kick(address gal, uint lot, uint bid) external returns (uint);
+ function kick(address gal, uint256 lot, uint256 bid) external returns (uint256);
function cage() external;
- function live() external returns (uint);
+ function live() external returns (uint256);
}
interface FlapLike {
- function kick(uint lot, uint bid) external returns (uint);
- function cage(uint) external;
- function live() external returns (uint);
+ function kick(uint256 lot, uint256 bid) external returns (uint256);
+ function cage(uint256) external;
+ function live() external returns (uint256);
}
interface VatLike {
- function dai (address) external view returns (uint);
- function sin (address) external view returns (uint);
+ function dai(address) external view returns (uint256);
+ function sin(address) external view returns (uint256);
function heal(uint256) external;
function hope(address) external;
function nope(address) external;
@@ -45,36 +45,43 @@ interface VatLike {
contract Vow {
// --- Auth ---
- mapping (address => uint) public wards;
- function rely(address usr) external auth { require(live == 1, "Vow/not-live"); wards[usr] = 1; }
- function deny(address usr) external auth { wards[usr] = 0; }
- modifier auth {
+ mapping(address => uint256) public wards;
+
+ function rely(address usr) external auth {
+ require(live == 1, "Vow/not-live");
+ wards[usr] = 1;
+ }
+
+ function deny(address usr) external auth {
+ wards[usr] = 0;
+ }
+ modifier auth() {
require(wards[msg.sender] == 1, "Vow/not-authorized");
_;
}
// --- Data ---
- VatLike public vat; // CDP Engine
- FlapLike public flapper; // Surplus Auction House
- FlopLike public flopper; // Debt Auction House
+ VatLike public vat; // CDP Engine
+ FlapLike public flapper; // Surplus Auction House
+ FlopLike public flopper; // Debt Auction House
- mapping (uint256 => uint256) public sin; // debt queue
- uint256 public Sin; // Queued debt [rad]
- uint256 public Ash; // On-auction debt [rad]
+ mapping(uint256 => uint256) public sin; // debt queue
+ uint256 public Sin; // Queued debt [rad]
+ uint256 public Ash; // On-auction debt [rad]
- uint256 public wait; // Flop delay [seconds]
- uint256 public dump; // Flop initial lot size [wad]
- uint256 public sump; // Flop fixed bid size [rad]
+ uint256 public wait; // Flop delay [seconds]
+ uint256 public dump; // Flop initial lot size [wad]
+ uint256 public sump; // Flop fixed bid size [rad]
- uint256 public bump; // Flap fixed lot size [rad]
- uint256 public hump; // Surplus buffer [rad]
+ uint256 public bump; // Flap fixed lot size [rad]
+ uint256 public hump; // Surplus buffer [rad]
- uint256 public live; // Active Flag
+ uint256 public live; // Active Flag
// --- Init ---
constructor(address vat_, address flapper_, address flopper_) public {
wards[msg.sender] = 1;
- vat = VatLike(vat_);
+ vat = VatLike(vat_);
flapper = FlapLike(flapper_);
flopper = FlopLike(flopper_);
vat.hope(flapper_);
@@ -82,18 +89,20 @@ contract Vow {
}
// --- Math ---
- function add(uint x, uint y) internal pure returns (uint z) {
+ function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
- function sub(uint x, uint y) internal pure returns (uint z) {
+
+ function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
- function min(uint x, uint y) internal pure returns (uint z) {
+
+ function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
return x <= y ? x : y;
}
// --- Administration ---
- function file(bytes32 what, uint data) external auth {
+ function file(bytes32 what, uint256 data) external auth {
if (what == "wait") wait = data;
else if (what == "bump") bump = data;
else if (what == "sump") sump = data;
@@ -107,30 +116,34 @@ contract Vow {
vat.nope(address(flapper));
flapper = FlapLike(data);
vat.hope(data);
+ } else if (what == "flopper") {
+ flopper = FlopLike(data);
+ } else {
+ revert("Vow/file-unrecognized-param");
}
- else if (what == "flopper") flopper = FlopLike(data);
- else revert("Vow/file-unrecognized-param");
}
// Push to debt-queue
- function fess(uint tab) external auth {
+ function fess(uint256 tab) external auth {
sin[now] = add(sin[now], tab);
Sin = add(Sin, tab);
}
+
// Pop from debt-queue
- function flog(uint era) external {
+ function flog(uint256 era) external {
require(add(era, wait) <= now, "Vow/wait-not-finished");
Sin = sub(Sin, sin[era]);
sin[era] = 0;
}
// Debt settlement
- function heal(uint rad) external {
+ function heal(uint256 rad) external {
require(rad <= vat.dai(address(this)), "Vow/insufficient-surplus");
require(rad <= sub(sub(vat.sin(address(this)), Sin), Ash), "Vow/insufficient-debt");
vat.heal(rad);
}
- function kiss(uint rad) external {
+
+ function kiss(uint256 rad) external {
require(rad <= Ash, "Vow/not-enough-ash");
require(rad <= vat.dai(address(this)), "Vow/insufficient-surplus");
Ash = sub(Ash, rad);
@@ -138,14 +151,15 @@ contract Vow {
}
// Debt auction
- function flop() external returns (uint id) {
+ function flop() external returns (uint256 id) {
require(sump <= sub(sub(vat.sin(address(this)), Sin), Ash), "Vow/insufficient-debt");
require(vat.dai(address(this)) == 0, "Vow/surplus-not-zero");
Ash = add(Ash, sump);
id = flopper.kick(address(this), dump, sump);
}
+
// Surplus auction
- function flap() external returns (uint id) {
+ function flap() external returns (uint256 id) {
require(vat.dai(address(this)) >= add(add(vat.sin(address(this)), bump), hump), "Vow/insufficient-surplus");
require(sub(sub(vat.sin(address(this)), Sin), Ash) == 0, "Vow/debt-not-zero");
id = flapper.kick(bump, 0);