diff --git a/cache_forge/solidity-files-cache.json b/cache_forge/solidity-files-cache.json index 876eeea..5af4d94 100644 --- a/cache_forge/solidity-files-cache.json +++ b/cache_forge/solidity-files-cache.json @@ -13,8 +13,8 @@ }, "files": { "contracts/InstadappAdapter.sol": { - "lastModificationDate": 1683185872563, - "contentHash": "067637daffbdabafdeef0cac3659a6ad", + "lastModificationDate": 1683847810570, + "contentHash": "405466b92e213e012519571fe719e3e9", "sourceName": "contracts/InstadappAdapter.sol", "solcConfig": { "settings": { @@ -60,8 +60,8 @@ } }, "contracts/InstadappTarget.sol": { - "lastModificationDate": 1683184056272, - "contentHash": "a1147b28e170ca0b1d6931155a1fd882", + "lastModificationDate": 1683848109539, + "contentHash": "92d6709ae5db0060d3d0e70d68b7a2ec", "sourceName": "contracts/InstadappTarget.sol", "solcConfig": { "settings": { @@ -157,8 +157,8 @@ } }, "forge-test/InstadappAdapter.t.sol": { - "lastModificationDate": 1683188978413, - "contentHash": "f1e1dc1e6d2fe020c27e7afa2c2f57d9", + "lastModificationDate": 1683849395973, + "contentHash": "af2e30ca53e944444016d11c12fb28d1", "sourceName": "forge-test/InstadappAdapter.t.sol", "solcConfig": { "settings": { @@ -226,8 +226,8 @@ } }, "forge-test/InstadappTarget.t.sol": { - "lastModificationDate": 1683188951507, - "contentHash": "09cf51949e601be2a7f175d6bbd50949", + "lastModificationDate": 1683849732441, + "contentHash": "573b9f3cca4252f41d9afc817136d975", "sourceName": "forge-test/InstadappTarget.t.sol", "solcConfig": { "settings": { diff --git a/contracts/InstadappAdapter.sol b/contracts/InstadappAdapter.sol index b5893fb..e511cc6 100644 --- a/contracts/InstadappAdapter.sol +++ b/contracts/InstadappAdapter.sol @@ -54,19 +54,25 @@ contract InstadappAdapter is EIP712 { /// @dev This function is used to forward the call to dsa.cast function. /// Cast the call is forwarded, the signature is verified and the salt is stored in the sigReplayProtection mapping. /// @param dsaAddress The address of the DSA. - /// @param auth The address of the auth. - /// @param signature The signature by the auth. This signature is used to verify the SIG data. - /// @param castData The data that will be sent to the targets. - /// @param salt The salt that will be used to prevent replay attacks. - /// @param deadline The deadline that will be used to prevent replay attacks. + /// @param _authcastCallData The data that will be sent to the targets and used for signature verification. function authCast( address dsaAddress, + bytes memory _authcastCallData + ) internal { + /// Decode the _authcastCallData + // auth: address of Authority, which whitelisted at dsaContract. + // signature: signature is signed by the auth includes the castData with salt. + // castData: CastData required for execution at destination + // salt: salt for Signature Replay Protection, which is unique to each signature signed by auth. + // deadline: deadline for the cast to be valid + ( address auth, bytes memory signature, CastData memory castData, bytes32 salt, uint256 deadline - ) internal { + ) = abi.decode(_authcastCallData, (address, bytes, CastData, bytes32, uint256)); + IDSA dsa = IDSA(dsaAddress); // check if Auth is valid, and included in the DSA require(auth != address(0) && dsa.isAuth(auth), "Invalid Auth"); diff --git a/contracts/InstadappTarget.sol b/contracts/InstadappTarget.sol index 7959956..ded8417 100644 --- a/contracts/InstadappTarget.sol +++ b/contracts/InstadappTarget.sol @@ -22,7 +22,7 @@ contract InstadappTarget is IXReceiver, InstadappAdapter { /// Events /// @dev This event is emitted when the authCast function is called. - event AuthCast(bytes32 indexed transferId, address indexed dsaAddress, bool indexed success, address auth, bytes returnedData); + event AuthCast(bytes32 indexed transferId, address indexed dsaAddress, bool indexed success, bytes authcastCallData, bytes returnedData); /// Modifiers /// @dev This modifier is used to ensure that only the Connext contract can call the function. @@ -40,9 +40,9 @@ contract InstadappTarget is IXReceiver, InstadappAdapter { /// Public functions /// @dev This function is used to receive funds from Connext and forward them to DSA. /// Then it forwards the call to authCast function. + /// @param _transferId The id of the transfer. /// @param _amount The amount of funds that will be received. /// @param _asset The address of the asset that will be received. - /// @param _transferId The id of the transfer. /// @param _callData The data that will be sent to the targets. function xReceive( bytes32 _transferId, @@ -54,19 +54,10 @@ contract InstadappTarget is IXReceiver, InstadappAdapter { ) external onlyConnext returns (bytes memory) { // Decode signed calldata // dsaAddress: address of DSA contract - // auth: address of Authority, which whitelisted at dsaContract. - // signature: signature is signed by the auth includes the castData with salt. - // castData: CastData required for execution at destination - // salt: salt for Signature Replay Protection, which is unique to each signature signed by auth. - // deadline: deadline for the cast to be valid ( address dsaAddress, - address auth, - bytes memory _signature, - CastData memory _castData, - bytes32 salt, - uint256 deadline - ) = abi.decode(_callData, (address, address, bytes, CastData, bytes32, uint256)); + bytes memory _authcastCallData + ) = abi.decode(_callData, (address, bytes)); // verify the dsaAddress require(dsaAddress != address(0), "!invalidFallback"); @@ -78,17 +69,13 @@ contract InstadappTarget is IXReceiver, InstadappAdapter { // calling via encodeWithSignature as alternative to try/catch (bool success, bytes memory returnedData) = address(this).call( abi.encodeWithSignature( - "authCast(address,address,bytes,CastData,bytes32,uint256)", + "authCast(address,bytes)", dsaAddress, - auth, - _signature, - _castData, - salt, - deadline + _authcastCallData ) ); - emit AuthCast(_transferId, dsaAddress, success, auth, returnedData); + emit AuthCast(_transferId, dsaAddress, success, _authcastCallData, returnedData); return returnedData; } diff --git a/forge-test/InstadappAdapter.t.sol b/forge-test/InstadappAdapter.t.sol index bb63c5c..9ef22eb 100644 --- a/forge-test/InstadappAdapter.t.sol +++ b/forge-test/InstadappAdapter.t.sol @@ -10,13 +10,9 @@ contract MockInstadappReceiver is InstadappAdapter { function tryAuthCast( address dsaAddress, - address auth, - bytes memory signature, - CastData memory castData, - bytes32 salt, - uint256 deadline + bytes memory authcastCallData ) external payable { - authCast(dsaAddress, auth, signature, castData, salt, deadline); + authCast(dsaAddress, authcastCallData); } function tryVerify( @@ -71,8 +67,16 @@ contract InstadappAdapterTest is TestHelper { address auth = originSender; bytes32 salt = bytes32(abi.encode(1)); + bytes memory authcastCallData = abi.encode( + auth, + signature, + castData, + salt, + deadline + ); + vm.expectRevert(bytes("Invalid Auth")); - MockInstadappReceiver(instadappReceiver).tryAuthCast(dsa, auth, signature, castData, salt, deadline); + MockInstadappReceiver(instadappReceiver).tryAuthCast(dsa, authcastCallData); } function test_InstadappAdapter__authCast_shouldRevertIfInvalidSignature() public { @@ -96,7 +100,16 @@ contract InstadappAdapterTest is TestHelper { address auth = originSender; bytes32 salt = bytes32(abi.encode(1)); vm.expectRevert(bytes("Invalid signature")); - MockInstadappReceiver(instadappReceiver).tryAuthCast(dsa, auth, signature, castData, salt, deadline); + + bytes memory authcastCallData = abi.encode( + auth, + signature, + castData, + salt, + deadline + ); + + MockInstadappReceiver(instadappReceiver).tryAuthCast(dsa, authcastCallData); } function test_InstadappAdapter__authCast_shouldWork() public { @@ -122,7 +135,16 @@ contract InstadappAdapterTest is TestHelper { address auth = originSender; vm.warp(timestamp); - MockInstadappReceiver(instadappReceiver).tryAuthCast{value: 1}(dsa, auth, signature, castData, salt, deadline); + + bytes memory authcastCallData = abi.encode( + auth, + signature, + castData, + salt, + deadline + ); + + MockInstadappReceiver(instadappReceiver).tryAuthCast(dsa, authcastCallData); } // ============ InstadappAdapter.verify ============ diff --git a/forge-test/InstadappTarget.t.sol b/forge-test/InstadappTarget.t.sol index 4f1ccfb..c8a4ab1 100644 --- a/forge-test/InstadappTarget.t.sol +++ b/forge-test/InstadappTarget.t.sol @@ -23,14 +23,10 @@ contract InstadappTargetTest is TestHelper, EIP712 { InstadappTarget instadappTarget; address instadappReceiver = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + uint256 deadline = 100; + // ============ Events ============ - event AuthCast( - bytes32 indexed transferId, - address indexed dsaAddress, - bool indexed success, - address auth, - bytes returnedData - ); + event AuthCast(bytes32 indexed transferId, address indexed dsaAddress, bool indexed success, bytes authcastCallData, bytes returnedData); // ============ Test set up ============ function setUp() public override { @@ -71,12 +67,21 @@ contract InstadappTargetTest is TestHelper, EIP712 { _datas[1] = bytes("0x222"); _datas[2] = bytes("0x333"); address _origin = originSender; + bytes32 salt = bytes32(0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef); InstadappAdapter.CastData memory castData = InstadappAdapter.CastData(_targetNames, _datas, _origin); bytes memory signature = hex"d75642b5e0cfceac682011943f3586fefc3709594a89bf8087acc58d2009d85412aca8b1f9b63989de45da85f5ffcea52cc5077a61a2128fa7322a97523afe0e1b"; address auth = originSender; - bytes memory callData = abi.encode(address(0), auth, signature, castData); + + bytes memory authcastCallData = abi.encode( + auth, + signature, + castData, + salt, + deadline + ); + bytes memory callData = abi.encode(address(0), authcastCallData); vm.prank(MOCK_CONNEXT); vm.expectRevert(bytes("!invalidFallback")); @@ -102,7 +107,6 @@ contract InstadappTargetTest is TestHelper, EIP712 { address _origin = originSender; address dsa = address(0x111222333); bytes32 salt = bytes32(0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef); - uint256 deadline = 10000; InstadappAdapter.CastData memory castData = InstadappAdapter.CastData(_targetNames, _datas, _origin); bytes32 digest = MockInstadappReceiver(instadappReceiver).tryGetDigest(castData, salt, deadline); @@ -110,11 +114,20 @@ contract InstadappTargetTest is TestHelper, EIP712 { (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); address auth = originSender; - bytes memory callData = abi.encode(dsa, auth, signature, castData); + + bytes memory authcastCallData = abi.encode( + auth, + signature, + castData, + salt, + deadline + ); + + bytes memory callData = abi.encode(dsa, authcastCallData); bytes memory returnedData = hex""; vm.expectEmit(true, false, false, true); - emit AuthCast(transferId, dsa, false, auth, returnedData); + emit AuthCast(transferId, dsa, false, authcastCallData, returnedData); deal(address(asset), address(instadappTarget), amount); vm.prank(MOCK_CONNEXT); instadappTarget.xReceive(transferId, amount, address(asset), address(0), 0, callData);