Skip to content

Commit add0397

Browse files
committed
added tests for CircuitBreakerPower
1 parent 49227e6 commit add0397

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

test/CircuitBreakerPower.t.sol

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import "forge-std/src/Test.sol";
5+
import "forge-std/src/console.sol";
6+
import "../src/CircuitBreakerPower.sol";
7+
import "./mock/MockERC20.sol";
8+
9+
contract CircuitBreakerPowerTest is Test {
10+
CircuitBreakerPower public circuitBreakerPower;
11+
bool testToken;
12+
13+
function setUp() public {
14+
address underlyingToken = address(new MockERC20("mock", "mock", 1e28));
15+
uint256 minLockAmount = 1000e18; // 1k units
16+
uint256 unlockDelaySec = 24 hours;
17+
uint256 unlockPeriodSec = 48 hours;
18+
uint8 unlockExponent = 1; // linear release
19+
20+
testToken = true;
21+
if (!testToken)
22+
underlyingToken = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
23+
24+
circuitBreakerPower = new CircuitBreakerPower(underlyingToken, minLockAmount, unlockDelaySec, unlockPeriodSec, unlockExponent, address(this));
25+
}
26+
27+
function testTransferNoFunds() public {
28+
vm.expectRevert("not enough tokens");
29+
circuitBreakerPower.transferTo(address(this), 1234);
30+
}
31+
32+
function testTransferNoLock() public {
33+
uint256 amount = 1e18;
34+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount);
35+
36+
vm.recordLogs();
37+
circuitBreakerPower.transferTo(address(this), amount);
38+
Vm.Log[] memory entries = vm.getRecordedLogs();
39+
assertEq(entries.length, 2);
40+
assertEq(entries[1].topics[0], keccak256("TransferFulfilled(address,uint256,uint256)"));
41+
assertEq(uint256(entries[1].topics[1]), uint256(uint160(address(this))));
42+
43+
(uint256 withdrawnAmount, uint256 remainingAmount) = abi.decode(entries[1].data, (uint256, uint256));
44+
assertEq(withdrawnAmount, amount);
45+
assertEq(remainingAmount, uint256(0));
46+
}
47+
48+
function testTransferLock() public {
49+
uint256 amount = 1000e18;
50+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount);
51+
52+
vm.recordLogs();
53+
circuitBreakerPower.transferTo(address(this), amount);
54+
Vm.Log[] memory entries = vm.getRecordedLogs();
55+
56+
assertEq(entries.length, 1);
57+
assertEq(entries[0].topics[0], keccak256("TransferLocked(address,uint256,uint256)"));
58+
assertEq(uint256(entries[0].topics[1]), uint256(uint160(address(this))));
59+
60+
(uint256 amountLocked, uint256 lockTimestamp) = abi.decode(entries[0].data, (uint256, uint256));
61+
assertEq(amountLocked, amount);
62+
assertEq(lockTimestamp, uint256(block.timestamp));
63+
64+
vm.warp(block.timestamp + 24 hours);
65+
uint256 withdrawableAmount0 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
66+
assertEq(withdrawableAmount0, 0);
67+
68+
vm.warp(block.timestamp + 24 hours);
69+
uint256 withdrawableAmount0_5 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
70+
assertEq(withdrawableAmount0_5, amount / 2);
71+
72+
vm.warp(block.timestamp + 24 hours);
73+
uint256 withdrawableAmount1 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
74+
assertEq(withdrawableAmount1, amount);
75+
}
76+
77+
function testTransferLockAndUnlock() public {
78+
uint256 amount = 1000e18;
79+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount);
80+
81+
vm.recordLogs();
82+
circuitBreakerPower.transferTo(address(this), amount);
83+
Vm.Log[] memory entries = vm.getRecordedLogs();
84+
85+
assertEq(entries.length, 1);
86+
assertEq(entries[0].topics[0], keccak256("TransferLocked(address,uint256,uint256)"));
87+
assertEq(uint256(entries[0].topics[1]), uint256(uint160(address(this))));
88+
89+
(uint256 amountLocked, uint256 lockTimestamp) = abi.decode(entries[0].data, (uint256, uint256));
90+
assertEq(amountLocked, amount);
91+
assertEq(lockTimestamp, uint256(block.timestamp));
92+
93+
vm.warp(block.timestamp + 24 hours);
94+
uint256 withdrawableAmount0 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
95+
assertEq(withdrawableAmount0, 0);
96+
97+
vm.warp(block.timestamp + 24 hours);
98+
uint256 withdrawableAmount0_5 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
99+
assertEq(withdrawableAmount0_5, amount / 2);
100+
101+
uint256 balanceBefore = IERC20(circuitBreakerPower.underlyingToken()).balanceOf(address(this));
102+
circuitBreakerPower.unlockFor(address(this), lockTimestamp);
103+
uint256 balanceAfter = IERC20(circuitBreakerPower.underlyingToken()).balanceOf(address(this));
104+
assertEq(balanceBefore + withdrawableAmount0_5 >= balanceAfter, true);
105+
106+
vm.warp(block.timestamp + 24 hours);
107+
uint256 withdrawableAmount1 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
108+
assertEq(withdrawableAmount1, amount - (balanceAfter - balanceBefore));
109+
110+
circuitBreakerPower.unlockFor(address(this), lockTimestamp);
111+
}
112+
113+
function testEarlyUnlock() public {
114+
uint256 amount = 1000e18;
115+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount);
116+
117+
vm.recordLogs();
118+
circuitBreakerPower.transferTo(address(this), amount);
119+
Vm.Log[] memory entries = vm.getRecordedLogs();
120+
121+
assertEq(entries.length, 1);
122+
assertEq(entries[0].topics[0], keccak256("TransferLocked(address,uint256,uint256)"));
123+
assertEq(uint256(entries[0].topics[1]), uint256(uint160(address(this))));
124+
125+
(uint256 amountLocked, uint256 lockTimestamp) = abi.decode(entries[0].data, (uint256, uint256));
126+
assertEq(amountLocked, amount);
127+
assertEq(lockTimestamp, uint256(block.timestamp));
128+
129+
vm.warp(block.timestamp + 24 hours);
130+
uint256 withdrawableAmount0 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
131+
assertEq(withdrawableAmount0, 0);
132+
133+
vm.warp(block.timestamp + 24 hours);
134+
uint256 withdrawableAmount0_5 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
135+
assertEq(withdrawableAmount0_5, amount / 2);
136+
137+
uint256 balanceBefore = IERC20(circuitBreakerPower.underlyingToken()).balanceOf(address(this));
138+
circuitBreakerPower.unlockFor(address(this), lockTimestamp);
139+
uint256 balanceAfter = IERC20(circuitBreakerPower.underlyingToken()).balanceOf(address(this));
140+
assertEq(balanceBefore + withdrawableAmount0_5 >= balanceAfter, true);
141+
142+
uint256 withdrawableAmount1 = circuitBreakerPower.getWithdrawableAmount(address(this), lockTimestamp);
143+
console.log(withdrawableAmount1);
144+
assertEq(withdrawableAmount1, 0);
145+
vm.expectRevert("no withdrawable funds");
146+
circuitBreakerPower.unlockFor(address(this), lockTimestamp);
147+
}
148+
149+
function testTransferNoLock2() public {
150+
uint256 amount2 = 2e18;
151+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount2);
152+
153+
vm.recordLogs();
154+
circuitBreakerPower.transferTo(address(this), amount2);
155+
Vm.Log[] memory entries = vm.getRecordedLogs();
156+
assertEq(entries.length, 2);
157+
assertEq(
158+
entries[1].topics[0],
159+
keccak256("TransferFulfilled(address,uint256,uint256)")
160+
);
161+
assertEq(
162+
uint256(entries[1].topics[1]),
163+
uint256(uint160(address(this)))
164+
);
165+
166+
(uint256 withdrawnAmount, uint256 remainingAmount) = abi.decode(
167+
entries[1].data,
168+
(uint256, uint256)
169+
);
170+
assertEq(withdrawnAmount, amount2);
171+
assertEq(remainingAmount, uint256(0));
172+
173+
uint256 amount = 1e18;
174+
IERC20(circuitBreakerPower.underlyingToken()).transfer(address(circuitBreakerPower), amount);
175+
176+
vm.recordLogs();
177+
178+
circuitBreakerPower.transferTo(address(this), amount);
179+
entries = vm.getRecordedLogs();
180+
assertEq(entries.length, 2);
181+
assertEq(
182+
entries[1].topics[0],
183+
keccak256("TransferFulfilled(address,uint256,uint256)")
184+
);
185+
assertEq(
186+
uint256(entries[1].topics[1]),
187+
uint256(uint160(address(this)))
188+
);
189+
190+
(withdrawnAmount, remainingAmount) = abi.decode(
191+
entries[1].data,
192+
(uint256, uint256)
193+
);
194+
assertEq(withdrawnAmount, amount);
195+
assertEq(remainingAmount, uint256(0));
196+
}
197+
}

0 commit comments

Comments
 (0)