|
1 | 1 | // SPDX-License-Identifier: AGPLv3 |
2 | 2 | pragma solidity ^0.8.23; |
3 | 3 |
|
4 | | -import { Test } from "forge-std/Test.sol"; |
| 4 | +import { Test, console } from "forge-std/Test.sol"; |
5 | 5 | import { UUPSProxy } from "../../../contracts/upgradability/UUPSProxy.sol"; |
6 | 6 | import { UUPSProxiable } from "../../../contracts/upgradability/UUPSProxiable.sol"; |
7 | | -import { IERC20, ISuperToken, SuperToken } |
| 7 | +import { IERC20, ISuperToken, ISuperfluidPool, PoolConfig } |
| 8 | + from "../../../contracts/interfaces/superfluid/ISuperfluid.sol"; |
| 9 | +import { SuperToken } |
8 | 10 | from "../../../contracts/superfluid/SuperToken.sol"; |
9 | 11 | import { PoolAdminNFT, IPoolAdminNFT } from "../../../contracts/agreements/gdav1/PoolAdminNFT.sol"; |
10 | 12 | import { FoundrySuperfluidTester } from "../FoundrySuperfluidTester.t.sol"; |
11 | 13 | import { TestToken } from "../../../contracts/utils/TestToken.sol"; |
12 | 14 | import { TokenDeployerLibrary } from "../../../contracts/utils/SuperfluidFrameworkDeploymentSteps.t.sol"; |
| 15 | +import { SuperTokenV1Library } from "../../../contracts/apps/SuperTokenV1Library.sol"; |
13 | 16 |
|
14 | 17 | contract SuperTokenIntegrationTest is FoundrySuperfluidTester { |
15 | | - constructor() FoundrySuperfluidTester(0) { } |
| 18 | + using SuperTokenV1Library for ISuperToken; |
| 19 | + |
| 20 | + constructor() FoundrySuperfluidTester(1) { } |
16 | 21 |
|
17 | 22 | function setUp() public override { |
18 | 23 | super.setUp(); |
@@ -254,4 +259,54 @@ contract SuperTokenIntegrationTest is FoundrySuperfluidTester { |
254 | 259 | assertEq(localSuperToken.nonces(permitSigner), 1, "Nonce should be incremented"); |
255 | 260 | assertEq(localSuperToken.allowance(permitSigner, spender), amount, "Allowance should be set"); |
256 | 261 | } |
| 262 | + |
| 263 | + // Verify zero Transfer events being emitted by CFA and GDA actions |
| 264 | + function testEmitZeroTransferEvent() public { |
| 265 | + vm.startPrank(admin); |
| 266 | + |
| 267 | + // case 1: create flow |
| 268 | + vm.expectEmit(address(superToken)); |
| 269 | + emit IERC20.Transfer(admin, alice, 0); |
| 270 | + superToken.createFlow(alice, 1); |
| 271 | + |
| 272 | + // case 2: delete flow |
| 273 | + vm.expectEmit(address(superToken)); |
| 274 | + emit IERC20.Transfer(admin, alice, 0); |
| 275 | + superToken.deleteFlow(admin, alice); |
| 276 | + |
| 277 | + // create a pool for the next tests |
| 278 | + ISuperfluidPool pool = superToken.createPool( |
| 279 | + admin, |
| 280 | + PoolConfig({ |
| 281 | + transferabilityForUnitsOwner: true, |
| 282 | + distributionFromAnyAddress: true |
| 283 | + }) |
| 284 | + ); |
| 285 | + |
| 286 | + // case 3: assign pool units |
| 287 | + vm.expectEmit(address(superToken)); |
| 288 | + emit IERC20.Transfer(address(pool), alice, 0); |
| 289 | + pool.updateMemberUnits(alice, 1); |
| 290 | + |
| 291 | + vm.stopPrank(); |
| 292 | + |
| 293 | + // case 4: test pool token transfer |
| 294 | + vm.startPrank(alice); |
| 295 | + // This emits 2 Transfer events, because the sender's units toggle to 0 and the receiver units from 0 |
| 296 | + vm.expectEmit(address(superToken)); |
| 297 | + emit IERC20.Transfer(address(pool), alice, 0); |
| 298 | + vm.expectEmit(address(superToken)); |
| 299 | + emit IERC20.Transfer(address(pool), bob, 0); |
| 300 | + IERC20(pool).transfer(bob, 1); |
| 301 | + |
| 302 | + vm.stopPrank(); |
| 303 | + |
| 304 | + // case 5: remove pool units |
| 305 | + vm.startPrank(admin); |
| 306 | + vm.expectEmit(address(superToken)); |
| 307 | + emit IERC20.Transfer(address(pool), bob, 0); |
| 308 | + pool.updateMemberUnits(bob, 0); |
| 309 | + |
| 310 | + vm.stopPrank(); |
| 311 | + } |
257 | 312 | } |
0 commit comments