Enhanced integration & optimized testing

This commit is contained in:
PedroCailleret
2023-02-14 18:40:02 -03:00
parent 4c8016080d
commit 8310e013f6
40 changed files with 1516 additions and 649 deletions

View File

@@ -0,0 +1,80 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/// @title Multicall.
/// @notice Contract that batches view function calls and aggregates their results.
/// @author Adapted from Makerdao's Multicall2 (https://github.com/makerdao/multicall/blob/master/src/Multicall2.sol).
contract Multicall {
/// @dev 0x
error CallFailed(string reason);
struct Call {
address target;
bytes callData;
}
struct Result {
bool success;
bytes returnData;
}
//prettier-ignore
constructor(/* */) payable {/* */}
function mtc1(Call[] calldata calls)
external
returns (uint256, bytes[] memory)
{
uint256 bn = block.number;
uint256 len = calls.length;
bytes[] memory res = new bytes[](len);
uint256 j;
while (j < len) {
(bool success, bytes memory ret) = calls[j]
.target
.call(calls[j].callData);
if (!success) {
if (ret.length < 0x44) revert CallFailed("");
assembly {
ret := add(ret, 0x04)
}
revert CallFailed({
reason: abi.decode(ret, (string))
});
}
res[j] = ret;
++j;
}
return (bn, res);
}
function mtc2(Call[] calldata calls)
external
returns (
uint256,
bytes32,
Result[] memory
)
{
uint256 bn = block.number;
// µ 0 s [0] ≡ P(IHp , µs [0], 0) ∴ P is the hash of a block of a particular number, up to a maximum age.
// 0 is left on the stack if the looked for `block.number` is >= to the current `block.number` or more than 256
// blocks behind the current block (Yellow Paper, p. 33, https://ethereum.github.io/yellowpaper/paper.pdf).
bytes32 bh = blockhash(
bn /* - 1 */
);
uint256 len = calls.length;
Result[] memory res = new Result[](len);
uint256 i;
for (i; i < len; ) {
(bool success, bytes memory ret) = calls[i]
.target
.call(calls[i].callData);
res[i] = Result(success, ret);
++i;
}
return (bn, bh, res);
}
}

View File

@@ -114,46 +114,4 @@ library SafeTransferLib {
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
assembly {
// We'll write our calldata to this slot below, but restore it later.
let memPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(
0,
0x095ea7b300000000000000000000000000000000000000000000000000000000
)
mstore(4, to) // Append the "to" argument.
mstore(36, amount) // Append the "amount" argument.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(
and(
eq(mload(0), 1),
gt(returndatasize(), 31)
),
iszero(returndatasize())
),
// We use 68 because that's the total length of our calldata (4 + 32 * 2)
// Counterintuitively, this call() must be positioned after the or() in the
// surrounding and() because and() evaluates its arguments from right to left.
call(gas(), token, 0, 0, 68, 0, 32)
)
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, memPointer) // Restore the memPointer.
}
require(success, "APPROVE_FAILED");
}
}