Skip to content

Commit d05b3f0

Browse files
committed
Write calldata/return data to the memory allocated via the free memory pointer
1 parent ac6c56b commit d05b3f0

File tree

3 files changed

+181
-126
lines changed

3 files changed

+181
-126
lines changed

contracts/base/FallbackManager.sol

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,37 @@ abstract contract FallbackManager is SelfAuthorized {
6464
// solhint-disable-next-line no-inline-assembly
6565
/// @solidity memory-safe-assembly
6666
assembly {
67+
// When compiled with the optimizer, the compiler relies on a certain assumptions on how the
68+
// memory is used, therefore we need to guarantee memory safety (keeping the free memory point 0x40 slot intact,
69+
// not going beyond the scratch space, etc)
70+
// Solidity docs: https://docs.soliditylang.org/en/latest/assembly.html#memory-safety
71+
function allocate(length) -> pos {
72+
pos := mload(0x40)
73+
mstore(0x40, add(pos, length))
74+
}
75+
6776
let handler := sload(slot)
6877
if iszero(handler) {
6978
return(0, 0)
7079
}
71-
calldatacopy(0, 0, calldatasize())
80+
81+
let calldataPtr := allocate(calldatasize())
82+
calldatacopy(calldataPtr, 0, calldatasize())
83+
7284
// The msg.sender address is shifted to the left by 12 bytes to remove the padding
7385
// Then the address without padding is stored right after the calldata
74-
mstore(calldatasize(), shl(96, caller()))
86+
let senderPtr := allocate(20)
87+
mstore(senderPtr, shl(96, caller()))
88+
7589
// Add 20 bytes for the address appended add the end
76-
let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)
77-
returndatacopy(0, 0, returndatasize())
90+
let success := call(gas(), handler, 0, calldataPtr, add(calldatasize(), 20), 0, 0)
91+
92+
let returnDataPtr := allocate(returndatasize())
93+
returndatacopy(returnDataPtr, 0, returndatasize())
7894
if iszero(success) {
79-
revert(0, returndatasize())
95+
revert(returnDataPtr, returndatasize())
8096
}
81-
return(0, returndatasize())
97+
return(returnDataPtr, returndatasize())
8298
}
8399
}
84100
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"eslint-plugin-prettier": "^4.2.1",
6868
"ethereum-waffle": "^3.3.0",
6969
"ethers": "5.4.0",
70-
"hardhat": "^2.2.1",
70+
"hardhat": "^2.14.0",
7171
"hardhat-deploy": "0.11.26",
7272
"husky": "^5.1.3",
7373
"prettier": "^2.8.4",

0 commit comments

Comments
 (0)