Skip to content

Commit

Permalink
support multi permits but spender specified transfers (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
snreynolds authored Nov 9, 2022
1 parent 77f61d9 commit dc8bb4b
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
143500
143701
2 changes: 1 addition & 1 deletion .forge-snapshots/permitBatchTransferFromSingleToken.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
88950
89017
2 changes: 1 addition & 1 deletion .forge-snapshots/permitTransferFromBatchTypedWitness.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
121317
121451
2 changes: 1 addition & 1 deletion .forge-snapshots/single recipient 2 tokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
118623
118757
2 changes: 1 addition & 1 deletion .forge-snapshots/single recipient many tokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
133765
134435
43 changes: 22 additions & 21 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,29 @@ Permit2LibTest:testTransferFrom2() (gas: 38404)
Permit2LibTest:testTransferFrom2Full() (gas: 53437)
Permit2LibTest:testTransferFrom2InvalidAmount() (gas: 12519)
Permit2LibTest:testTransferFrom2NonPermitToken() (gas: 53305)
SignatureTransferTest:testGasMultiplePermitBatchTransferFrom() (gas: 270959)
SignatureTransferTest:testGasSinglePermitBatchTransferFrom() (gas: 186309)
SignatureTransferTest:testGasSinglePermitTransferFrom() (gas: 124095)
SignatureTransferTest:testInvalidateUnorderedNonces() (gas: 56540)
SignatureTransferTest:testPermitBatchTransferFrom() (gas: 162076)
SignatureTransferTest:testPermitBatchTransferFromSingleRecipient() (gas: 190355)
SignatureTransferTest:testPermitBatchTransferFromTypedWitness() (gas: 242493)
SignatureTransferTest:testGasMultiplePermitBatchTransferFrom() (gas: 271182)
SignatureTransferTest:testGasSinglePermitBatchTransferFrom() (gas: 186398)
SignatureTransferTest:testGasSinglePermitTransferFrom() (gas: 124117)
SignatureTransferTest:testInvalidateUnorderedNonces() (gas: 56562)
SignatureTransferTest:testPermitBatchMultiPermitSingleTransfer() (gas: 133761)
SignatureTransferTest:testPermitBatchTransferFrom() (gas: 162210)
SignatureTransferTest:testPermitBatchTransferFromSingleRecipient() (gas: 190511)
SignatureTransferTest:testPermitBatchTransferFromTypedWitness() (gas: 242649)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidType() (gas: 87340)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidTypeHash() (gas: 86803)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidTypeName() (gas: 88276)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidWitness() (gas: 88321)
SignatureTransferTest:testPermitBatchTransferInvalidAmountsLengthMismatch() (gas: 43738)
SignatureTransferTest:testPermitBatchTransferMultiAddr() (gas: 160450)
SignatureTransferTest:testPermitBatchTransferSingleRecipientManyTokens() (gas: 211974)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidTypeHash() (gas: 86825)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidTypeName() (gas: 88298)
SignatureTransferTest:testPermitBatchTransferFromTypedWitnessInvalidWitness() (gas: 88343)
SignatureTransferTest:testPermitBatchTransferInvalidAmountsLengthMismatch() (gas: 43760)
SignatureTransferTest:testPermitBatchTransferMultiAddr() (gas: 160606)
SignatureTransferTest:testPermitBatchTransferSingleRecipientManyTokens() (gas: 212666)
SignatureTransferTest:testPermitTransferFrom() (gas: 93208)
SignatureTransferTest:testPermitTransferFromCompactSig() (gas: 124159)
SignatureTransferTest:testPermitTransferFromCompactSig() (gas: 124181)
SignatureTransferTest:testPermitTransferFromIncorrectSigLength() (gas: 51430)
SignatureTransferTest:testPermitTransferFromInvalidNonce() (gas: 93215)
SignatureTransferTest:testPermitTransferFromRandomNonceAndAmount(uint256,uint128) (runs: 256, μ: 95842, ~: 96818)
SignatureTransferTest:testPermitTransferFromToSpender() (gas: 93494)
SignatureTransferTest:testPermitTransferFromInvalidNonce() (gas: 93237)
SignatureTransferTest:testPermitTransferFromRandomNonceAndAmount(uint256,uint128) (runs: 256, μ: 95864, ~: 96840)
SignatureTransferTest:testPermitTransferFromToSpender() (gas: 93516)
SignatureTransferTest:testPermitTransferFromTypedWitness() (gas: 127964)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidType() (gas: 58668)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidTypeName() (gas: 59722)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidTypehash() (gas: 57658)
SignatureTransferTest:testPermitTransferSpendLessThanFull(uint256,uint128) (runs: 256, μ: 98177, ~: 99895)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidType() (gas: 58690)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidTypeName() (gas: 59744)
SignatureTransferTest:testPermitTransferFromTypedWitnessInvalidTypehash() (gas: 57680)
SignatureTransferTest:testPermitTransferSpendLessThanFull(uint256,uint128) (runs: 256, μ: 98199, ~: 99917)
5 changes: 4 additions & 1 deletion src/SignatureTransfer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ contract SignatureTransfer is ISignatureTransfer, EIP712 {

if (requestedAmount > permitted.amount) revert InvalidAmount();

ERC20(permitted.token).safeTransferFrom(owner, transferDetails[i].to, requestedAmount);
if (requestedAmount != 0) {
// allow spender to specify which of the permitted tokens should be transferred
ERC20(permitted.token).safeTransferFrom(owner, transferDetails[i].to, requestedAmount);
}
}
}
}
Expand Down
29 changes: 28 additions & 1 deletion test/SignatureTransfer.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ contract SignatureTransferTest is Test, PermitSignature, TokenProvider, GasSnaps
ISignatureTransfer.PermitBatchTransferFrom memory permit = defaultERC20PermitMultiple(tokens, nonce);
bytes memory sig = getPermitBatchTransferSignature(permit, fromPrivateKey, DOMAIN_SEPARATOR);

// address(0) gets sent to spender
address[] memory to = AddressBuilder.fill(1, address(address2)).push(address(address0));
ISignatureTransfer.SignatureTransferDetails[] memory toAmountPairs =
StructBuilder.fillSigTransferDetails(defaultAmount, to);
Expand All @@ -204,6 +203,34 @@ contract SignatureTransferTest is Test, PermitSignature, TokenProvider, GasSnaps
assertEq(token1.balanceOf(address0), startBalanceTo1 + defaultAmount);
}

function testPermitBatchMultiPermitSingleTransfer() public {
uint256 nonce = 0;
address[] memory tokens = AddressBuilder.fill(1, address(token0)).push(address(token1));
ISignatureTransfer.PermitBatchTransferFrom memory permit = defaultERC20PermitMultiple(tokens, nonce);

bytes memory sig = getPermitBatchTransferSignature(permit, fromPrivateKey, DOMAIN_SEPARATOR);

// must fill address to even though token0 wont get sent.
// transfer details must be lenght of permit
address[] memory to = AddressBuilder.fill(1, address(address0)).push(address(address0));
ISignatureTransfer.SignatureTransferDetails[] memory toAmountPairs =
StructBuilder.fillSigTransferDetails(defaultAmount, to);
// spender doesnt need token0 even though user permitted it
toAmountPairs[0].requestedAmount = 0;

uint256 startBalanceFrom0 = token0.balanceOf(from);
uint256 startBalanceFrom1 = token1.balanceOf(from);
uint256 startBalanceTo0 = token0.balanceOf(address2);
uint256 startBalanceTo1 = token1.balanceOf(address0);

permit2.permitTransferFrom(permit, from, toAmountPairs, sig);

assertEq(token0.balanceOf(from), startBalanceFrom0);
assertEq(token1.balanceOf(from), startBalanceFrom1 - defaultAmount);
assertEq(token0.balanceOf(address2), startBalanceTo0);
assertEq(token1.balanceOf(address0), startBalanceTo1 + defaultAmount);
}

function testPermitBatchTransferFromSingleRecipient() public {
uint256 nonce = 0;
address[] memory tokens = AddressBuilder.fill(1, address(token0)).push(address(token1));
Expand Down

0 comments on commit dc8bb4b

Please sign in to comment.