11pragma solidity ^ 0.4.24 ;
22
3+ import "./IRelayer.sol " ;
34import "./RelayedAragonApp.sol " ;
45import "../lib/sig/ECDSA.sol " ;
56import "../apps/AragonApp.sol " ;
7+ import "../common/MemoryHelpers.sol " ;
68import "../common/DepositableStorage.sol " ;
79
810
9- contract Relayer is AragonApp , DepositableStorage {
11+ contract Relayer is IRelayer , AragonApp , DepositableStorage {
1012 using ECDSA for bytes32 ;
13+ using MemoryHelpers for bytes ;
1114
1215 bytes32 public constant ALLOW_OFF_CHAIN_SERVICE_ROLE = keccak256 ("ALLOW_OFF_CHAIN_SERVICE_ROLE " );
1316 bytes32 public constant DISALLOW_OFF_CHAIN_SERVICE_ROLE = keccak256 ("DISALLOW_OFF_CHAIN_SERVICE_ROLE " );
@@ -21,7 +24,7 @@ contract Relayer is AragonApp, DepositableStorage {
2124
2225 event ServiceAllowed (address indexed service );
2326 event ServiceDisallowed (address indexed service );
24- event TransactionRelayed (address indexed from , address indexed to , uint256 nonce , bytes calldata );
27+ event TransactionRelayed (address from , address to , uint256 nonce , bytes calldata );
2528
2629 mapping (address => bool ) internal allowedServices;
2730 mapping (address => uint256 ) internal lastUsedNonce;
@@ -48,8 +51,9 @@ contract Relayer is AragonApp, DepositableStorage {
4851 assertValidTransaction (from, nonce, calldata , signature);
4952
5053 lastUsedNonce[from] = nonce;
51- IRelayedAragonApp (to). exec ( from, calldata );
54+ relayCall ( from, to , calldata );
5255 emit TransactionRelayed (from, to, nonce, calldata );
56+ forwardReturnedData ();
5357 }
5458
5559 function allowService (address service ) external authP (ALLOW_OFF_CHAIN_SERVICE_ROLE, arr (service)) {
@@ -84,4 +88,24 @@ contract Relayer is AragonApp, DepositableStorage {
8488 function messageHash (bytes calldata , uint256 nonce ) internal pure returns (bytes32 ) {
8589 return keccak256 (abi.encodePacked (keccak256 (calldata ), nonce));
8690 }
91+
92+ function relayCall (address from , address to , bytes calldata ) private {
93+ bytes memory encodedSignerCalldata = calldata .append (from);
94+ assembly {
95+ let success := call (gas, to, 0 , add (encodedSignerCalldata, 0x20 ), mload (encodedSignerCalldata), 0 , 0 )
96+ switch success case 0 {
97+ let ptr := mload (0x40 )
98+ returndatacopy (ptr, 0 , returndatasize)
99+ revert (ptr, returndatasize)
100+ }
101+ }
102+ }
103+
104+ function forwardReturnedData () private {
105+ assembly {
106+ let ptr := mload (0x40 )
107+ returndatacopy (ptr, 0 , returndatasize)
108+ return (ptr, returndatasize)
109+ }
110+ }
87111}
0 commit comments