Skip to content

Commit

Permalink
βœ… Benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
transmissions11 committed Jul 20, 2022
1 parent 62297af commit 3f921a0
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/rari-capital/solmate
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at d3ff81
4 changes: 4 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ds-test/=lib/solmate/lib/ds-test/src/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
solmate/=lib/solmate/src/
9 changes: 4 additions & 5 deletions src/Approve2Lib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,13 @@ contract Approve2Lib {
bytes32 r,
bytes32 s
) internal virtual {
Approve2 approve2 = APPROVE2;

assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)

// Write the abi-encoded calldata into memory, beginning
// with the function selector for EIP-2612 DOMAIN_SEPARATOR.
mstore(freeMemoryPointer, 0x0df6321000000000000000000000000000000000000000000000000000000000)
mstore(freeMemoryPointer, 0x3644e51500000000000000000000000000000000000000000000000000000000)

let success := and(
// Should resolve false if it returned <32 bytes or its first word is 0.
Expand Down Expand Up @@ -185,7 +183,7 @@ contract Approve2Lib {
//////////////////////////////////////////////////////////////*/

// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x12d7a2bc00000000000000000000000000000000000000000000000000000000)
mstore(freeMemoryPointer, 0xd505accf00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), owner) // Append the "owner" argument.
mstore(add(freeMemoryPointer, 36), spender) // Append the "spender" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.
Expand Down Expand Up @@ -218,7 +216,8 @@ contract Approve2Lib {
mstore(add(freeMemoryPointer, 228), s) // Append the "s" argument.

// We use 260 because the length of our calldata totals up like so: 4 + 32 * 8.
if iszero(call(gas(), approve2, 0, freeMemoryPointer, 260, 0, 0)) {
// TODO: stack too deep so had to inline, will need to figure this out
if iszero(call(gas(), 0xce71065d4017f316ec606fe4422e11eb2c47c246, 0, freeMemoryPointer, 260, 0, 0)) {
// Bubble up any revert reasons returned.
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
Expand Down
97 changes: 93 additions & 4 deletions test/Approve2.t.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,103 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {SafeERC20, IERC20, IERC20Permit} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";

import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol";
import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol";

import {Approve2} from "../src/Approve2.sol";
import {Approve2Lib} from "../src/Approve2Lib.sol";

contract Approve2Test is DSTestPlus, Approve2Lib {
bytes32 constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

bytes32 immutable DOMAIN_SEPARATOR;

Approve2 immutable approve2 = new Approve2();

MockERC20 immutable token = new MockERC20("Mock Token", "MOCK", 18);

constructor() Approve2Lib(approve2) {
DOMAIN_SEPARATOR = token.DOMAIN_SEPARATOR();

token.mint(address(this), type(uint128).max);

token.approve(address(this), type(uint128).max);
}

/*//////////////////////////////////////////////////////////////
BASIC PERMIT2 BENCHMARKS
//////////////////////////////////////////////////////////////*/

function testStandardPermit() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);

(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);

token.permit(owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}

function testOZSafePermit() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);

(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);

SafeERC20.safePermit(IERC20Permit(address(token)), owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}

function testPermit2() public {
uint256 privateKey = 0xBEEF;
address owner = hevm.addr(privateKey);

(uint8 v, bytes32 r, bytes32 s) = hevm.sign(
privateKey,
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, address(0xCAFE), 1e18, 0, block.timestamp))
)
)
);

contract Approve2Test is DSTestPlus {
Approve2 approve2;
permit2(token, owner, address(0xCAFE), 1e18, block.timestamp, v, r, s);
}

/*//////////////////////////////////////////////////////////////
BASIC TRANSFERFROM2 BENCHMARKS
//////////////////////////////////////////////////////////////*/

function testStandardTransferFrom() public {
token.transferFrom(address(this), address(0xBEEF), 1e18);
}

function testOZSafeTransferFrom() public {
SafeERC20.safeTransferFrom(IERC20(address(token)), address(this), address(0xBEEF), 1e18);
}

function setUp() public {
approve2 = new Approve2();
function testTransferFrom2() public {
transferFrom2(token, address(this), address(0xBEEF), 1e18);
}
}

0 comments on commit 3f921a0

Please sign in to comment.