Skip to content

Commit

Permalink
Merge pull request 1inch#67 from 1inch/feature/packed_permit2
Browse files Browse the repository at this point in the history
[SC-737] Packed permit2
  • Loading branch information
ZumZoom authored Feb 17, 2023
2 parents 31a399d + a82c2a4 commit 60fa6eb
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
24 changes: 20 additions & 4 deletions contracts/libraries/SafeERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,10 @@ library SafeERC20 {

// Compact IDaiLikePermit.permit(uint32 nonce, uint32 expiry, uint256 r, uint256 vs)
{ // stack too deep
let nonce := shr(224, calldataload(permit.offset))
let expiry := shr(224, calldataload(add(permit.offset, 0x04)))
let vs := calldataload(add(permit.offset, 0x28))

mstore(add(ptr, 0x44), nonce)
mstore(add(ptr, 0x44), shr(224, calldataload(permit.offset)))
mstore(add(ptr, 0x64), sub(expiry, 1))
mstore(add(ptr, 0x84), true)
mstore(add(ptr, 0xa4), add(27, shr(255, vs)))
Expand All @@ -215,12 +214,29 @@ library SafeERC20 {
// IDaiLikePermit.permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s)
success := call(gas(), token, 0, ptr, add(4, permit.length), 0, 0)
}
case 128 {
// Compact IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
mstore(ptr, permit2Selector)
mstore(add(ptr, 0x04), owner)
mstore(add(ptr, 0x24), token)
calldatacopy(add(ptr, 0x50), permit.offset, 0x14) // amount
calldatacopy(add(ptr, 0x7e), add(permit.offset, 0x14), 0x06) // expiration
calldatacopy(add(ptr, 0x9e), add(permit.offset, 0x1a), 0x06) // nonce
mstore(add(ptr, 0xa4), spender)
calldatacopy(add(ptr, 0xc4), add(permit.offset, 0x20), 0x20) // sigDeadline
mstore(add(ptr, 0xe4), 0x100)
mstore(add(ptr, 0x104), 0x40)
calldatacopy(add(ptr, 0x124), add(permit.offset, 0x40), 0x20) // r
calldatacopy(add(ptr, 0x144), add(permit.offset, 0x60), 0x20) // vs
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 388, 0, 0)
}
case 384 {
mstore(ptr, permit2Selector)
calldatacopy(add(ptr, 0x04), permit.offset, permit.length)
success := call(gas(), _PERMIT2, 0, ptr, add(4, permit.length), 0, 0)
// IPermit2.permit(address owner, PermitSingle calldata permitSingle, bytes calldata signature)
success := call(gas(), _PERMIT2, 0, ptr, 388, 0, 0)
}
// TODO: add case for compact permit2
default {
mstore(ptr, _PERMIT_LENGHT_ERROR)
revert(ptr, 4)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@1inch/solidity-utils",
"version": "2.2.16",
"version": "2.2.17",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"repository": {
Expand Down
7 changes: 7 additions & 0 deletions src/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export async function getPermit2(
chainId: number,
spender: string,
amount: bigint,
compact = false,
expiration = defaultDeadlinePermit2,
sigDeadline = defaultDeadlinePermit2,
) {
Expand All @@ -182,6 +183,12 @@ export async function getPermit2(
};
const data = AllowanceTransfer.getPermitData(permitSingle, permitContract.address, chainId);
const signature = await owner._signTypedData(data.domain, data.types, data.values);
const { v, r, s } = ethers.utils.splitSignature(signature);
if (compact) {
return '0x' + amount.toString(16).padStart(40, '0') + expiration.toString(16).padStart(12, '0') +
BigInt(nonce).toString(16).padStart(12, '0') + sigDeadline.toString(16).padStart(64, '0') +
BigInt(r).toString(16).padStart(64, '0') + (BigInt(s) | (BigInt(v - 27) << 255n)).toString(16).padStart(64, '0');
}
const permitCall = await permitContract.populateTransaction.permit(owner.address, permitSingle, signature);
return cutSelector(permitCall.data!);
}
Expand Down
11 changes: 11 additions & 0 deletions test/Permitable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ describe('Permitable', function () {
expect(allowance.nonce).to.equal(1);
});

it('should be permitted for IPermit2, compact', async function () {
const { permitableMock, daiLikePermitMock, chainId } = await loadFixture(deployTokens);
const permitContract = await permit2Contract();
const permit = await getPermit2(signer1, daiLikePermitMock.address, chainId, permitableMock.address, constants.MAX_UINT128, true);
await permitableMock.mockPermitCompact(daiLikePermitMock.address, permit);

const allowance = await permitContract.allowance(signer1.address, daiLikePermitMock.address, permitableMock.address);
expect(allowance.amount).to.equal(constants.MAX_UINT128);
expect(allowance.nonce).to.equal(1);
});

it('should be permitted for IDaiLikePermit (compact)', async function () {
const { permitableMock, daiLikePermitMock, chainId } = await loadFixture(deployTokens);

Expand Down

0 comments on commit 60fa6eb

Please sign in to comment.