Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 0 additions & 233 deletions contracts/test/GenericCallForwarder.integration.t.sol

This file was deleted.

14 changes: 6 additions & 8 deletions contracts/test/GenericCallForwarder.unit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {IERC1271} from "@openzeppelin-contracts-5.6.1/interfaces/IERC1271.sol";
import {IERC20} from "@openzeppelin-contracts-5.6.1/token/ERC20/IERC20.sol";
import {Errors} from "@openzeppelin-contracts-5.6.1/utils/Errors.sol";
import {ReentrancyGuardTransient} from "@openzeppelin-contracts-5.6.1/utils/ReentrancyGuardTransient.sol";
import {IForwarder} from "anoma-forwarder-bases-1.0.0-rc.3/src/interfaces/IForwarder.sol";
import {IVersion} from "anoma-forwarder-bases-1.0.0-rc.3/src/interfaces/IVersion.sol";
import {ERC20Example} from "anomapay-erc20-forwarder-1.1.0-rc.2/test/examples/ERC20.e.sol";
import {Test} from "forge-std-1.16.1/src/Test.sol";
Expand All @@ -26,7 +25,7 @@ contract GenericCallForwarderTest is Test {

address internal _alice;

IForwarder internal _genericCallFwd;
GenericCallForwarder internal _genericCallFwd;

WETH internal _weth;

Expand Down Expand Up @@ -182,12 +181,11 @@ contract GenericCallForwarderTest is Test {
_genericCallFwd.forwardCall({logicRef: _genericCallResourceLogicRef, input: abi.encode(calls)});
}

function test_isValidSignature_always_returns_the_ERC1271_magic_value() public view {
bytes4 magic = IERC1271.isValidSignature.selector;

assertEq(IERC1271(address(_genericCallFwd)).isValidSignature(bytes32(0), ""), magic);
assertEq(IERC1271(address(_genericCallFwd)).isValidSignature(keccak256("anoma"), hex"cafe"), magic);
assertEq(IERC1271(address(_genericCallFwd)).isValidSignature(bytes32(type(uint256).max), hex"00"), magic);
function testFuzz_isValidSignature_always_returns_the_ERC1271_magic_value(bytes32 hash, bytes calldata signature)
public
view
{
assertEq(_genericCallFwd.isValidSignature(hash, signature), IERC1271.isValidSignature.selector);
}

function test_check_that_the_current_version_is_a_pre_release_of_v1_0_0() public view {
Expand Down
108 changes: 108 additions & 0 deletions contracts/test/integration/GenericCallForwarder.native.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {IForwarder} from "anoma-forwarder-bases-1.0.0-rc.3/src/interfaces/IForwarder.sol";
import {INativeTokenReceiver} from "anoma-forwarder-bases-1.0.0-rc.3/src/interfaces/INativeTokenReceiver.sol";
import {ERC20Forwarder} from "anomapay-erc20-forwarder-1.1.0-rc.2/src/ERC20Forwarder.sol";
import {Test} from "forge-std-1.16.1/src/Test.sol";

import {WETH} from "solady-0.1.26/src/tokens/WETH.sol";

import {GenericCallForwarder} from "../../src/GenericCallForwarder.sol";

contract GenericCallForwarderNativeTest is Test {
address internal constant _PROTOCOL_ADAPTER = address(uint160(1));
address internal constant _EMERGENCY_COMMITTEE = address(uint160(2));
uint128 internal constant _TRANSFER_AMOUNT = 1000;
bytes internal constant _EXPECTED_OUTPUT = "";

bytes32 internal _erc20ResourceLogicRef;
bytes32 internal _genericCallResourceLogicRef;

address internal _alice;

IForwarder internal _erc20Fwd;
IForwarder internal _genericCallFwd;

WETH internal _weth;

bytes internal _defaultUnwrapInput;

function setUp() public {
_erc20ResourceLogicRef = bytes32(uint256(1));
_genericCallResourceLogicRef = bytes32(uint256(2));

_alice = makeAddr("alice");

_weth = new WETH();

// Deploy the forwarders
_erc20Fwd = new ERC20Forwarder({
protocolAdapter: _PROTOCOL_ADAPTER,
emergencyCommittee: _EMERGENCY_COMMITTEE,
logicRef: _erc20ResourceLogicRef
});
_genericCallFwd =
new GenericCallForwarder({protocolAdapter: _PROTOCOL_ADAPTER, logicRef: _genericCallResourceLogicRef});

_defaultUnwrapInput = abi.encode( /* callType */
ERC20Forwarder.CallType.Unwrap,
/* token */
address(_weth),
/* amount */
_TRANSFER_AMOUNT,
/* unwrap data */
ERC20Forwarder.UnwrapData({receiver: address(_genericCallFwd)})
);
}

function test_calls_allow_to_unwrap_native_tokens() public {
// Fund Generic Call Forwarder with WETH
{
vm.deal(address(_erc20Fwd), _TRANSFER_AMOUNT);
vm.prank(address(_erc20Fwd));
_weth.deposit{value: _TRANSFER_AMOUNT}();
}

assertEq(_weth.balanceOf(address(_erc20Fwd)), _TRANSFER_AMOUNT);
assertEq(_weth.balanceOf(address(_genericCallFwd)), 0);
assertEq(_alice.balance, 0);

// Mock ERC20Forwarder call (triggered by TokenTransfer resource)
{
// Unwrap WETH-R into the generic call forwarder
vm.prank(_PROTOCOL_ADAPTER);
bytes memory output1 = _erc20Fwd.forwardCall({logicRef: _erc20ResourceLogicRef, input: _defaultUnwrapInput});
assertEq(keccak256(output1), keccak256(_EXPECTED_OUTPUT));
}

assertEq(_weth.balanceOf(address(_erc20Fwd)), 0);
assertEq(_weth.balanceOf(address(_genericCallFwd)), _TRANSFER_AMOUNT);
assertEq(_alice.balance, 0);

// Mock GenericCallForwarder call (triggered by GenericCall resource)
{
GenericCallForwarder.Call[] memory genericCalls = new GenericCallForwarder.Call[](2);
// Call 1: Unwrap WETH
genericCalls[0] = GenericCallForwarder.Call({
to: address(_weth), value: 0, data: abi.encodeCall(WETH.withdraw, uint256(_TRANSFER_AMOUNT))
});
// Call 2: Transfer ETH
genericCalls[1] = GenericCallForwarder.Call({to: _alice, value: _TRANSFER_AMOUNT, data: ""});
bytes memory _unwrapWethAndTransferEthInput = abi.encode(genericCalls);

vm.prank(_PROTOCOL_ADAPTER);
vm.expectEmit(address(_genericCallFwd));
emit INativeTokenReceiver.NativeTokenReceived({sender: address(_weth), amount: _TRANSFER_AMOUNT});

bytes memory output2 = _genericCallFwd.forwardCall({
logicRef: _genericCallResourceLogicRef, input: _unwrapWethAndTransferEthInput
});
assertEq(keccak256(output2), keccak256(_EXPECTED_OUTPUT));
}

assertEq(_weth.balanceOf(address(_erc20Fwd)), 0);
assertEq(_weth.balanceOf(address(_genericCallFwd)), 0);
assertEq(_alice.balance, _TRANSFER_AMOUNT);
}
}
Loading
Loading