Skip to content

Commit 4bbbd2e

Browse files
committed
added test for grifting case
1 parent 5f695a2 commit 4bbbd2e

File tree

2 files changed

+418
-62
lines changed

2 files changed

+418
-62
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.23;
3+
4+
import {
5+
ISuperToken
6+
} from "../../../contracts/interfaces/superfluid/ISuperfluid.sol";
7+
import {
8+
IERC20
9+
} from "../../../contracts/interfaces/superfluid/ISuperfluid.sol";
10+
11+
import { ISETH } from "../../../contracts/interfaces/tokens/ISETH.sol";
12+
13+
import "forge-std/console.sol";
14+
15+
contract GrifterContract {
16+
ISuperToken public immutable superToken;
17+
IERC20 public immutable underlyingToken;
18+
IERC20 public immutable aToken;
19+
uint256 public immutable amount;
20+
21+
constructor(ISuperToken _superToken, IERC20 _aToken, uint256 _amount) {
22+
superToken = _superToken;
23+
aToken = _aToken;
24+
underlyingToken = IERC20(superToken.getUnderlyingToken());
25+
amount = _amount;
26+
27+
if (address(underlyingToken) != address(0)) {
28+
// Approve SuperToken to move underlying
29+
underlyingToken.approve(address(superToken), type(uint256).max);
30+
}
31+
}
32+
33+
receive() external payable {}
34+
35+
function grift(uint256 iterations) external {
36+
if (address(underlyingToken) == address(0)) {
37+
// Native ETH path
38+
for (uint256 i = 0; i < iterations; ++i) {
39+
uint256 bal0 = aToken.balanceOf(address(superToken));
40+
41+
// Upgrade ETH
42+
ISETH(address(superToken)).upgradeByETH{ value: amount }();
43+
44+
uint256 bal1 = aToken.balanceOf(address(superToken));
45+
46+
// Downgrade ETH
47+
ISETH(address(superToken)).downgradeToETH(amount);
48+
49+
uint256 bal2 = aToken.balanceOf(address(superToken));
50+
51+
// Analyze Downgrade
52+
if (bal2 < bal1) {
53+
uint256 burned = bal1 - bal2;
54+
if (burned > amount) {
55+
uint256 diff = burned - amount;
56+
console.log("ETHx Downgrade Excess FOUND:");
57+
console.log(" Req: %s", amount);
58+
console.log(" Burn: %s", burned);
59+
console.log(" Diff: %s", diff);
60+
revert("FOUND EXCESS BURN");
61+
}
62+
}
63+
}
64+
} else {
65+
// ERC20 Path
66+
for (uint256 i = 0; i < iterations; ++i) {
67+
uint256 bal0 = aToken.balanceOf(address(superToken));
68+
69+
superToken.upgrade(amount);
70+
71+
uint256 bal1 = aToken.balanceOf(address(superToken));
72+
73+
superToken.downgrade(amount);
74+
uint256 bal2 = aToken.balanceOf(address(superToken));
75+
76+
// Analyze Downgrade
77+
if (bal2 < bal1) {
78+
uint256 burned = bal1 - bal2;
79+
if (burned > amount) {
80+
uint256 diff = burned - amount;
81+
console.log("ERC20 Downgrade Excess FOUND:");
82+
console.log(" Req: %s", amount);
83+
console.log(" Burn: %s", burned);
84+
console.log(" Diff: %s", diff);
85+
revert("FOUND EXCESS BURN");
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)