Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve test coverage action [@coderabbit ignore] #790

Closed
wants to merge 40 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e4c5947
Add Permit2Proxy
ezynda3 Aug 22, 2024
797e772
Add Permit2Proxy
ezynda3 Aug 22, 2024
48b9703
forge install: Permit2
ezynda3 Aug 22, 2024
9795b16
Get basic test working...
ezynda3 Aug 23, 2024
745c5c7
Add more basic tests
ezynda3 Aug 26, 2024
e186436
Remove superfluous receiver param
ezynda3 Aug 26, 2024
143d4c2
Add utility method for getting a valid and working msgHash to sign
ezynda3 Aug 26, 2024
779bd8b
Change name to be more specific
ezynda3 Aug 26, 2024
f36a67e
Add Permit "v1" functionality
ezynda3 Aug 26, 2024
48de477
Add Permit "v1" tests
ezynda3 Aug 26, 2024
d119ca9
Add missing comments
ezynda3 Aug 26, 2024
484c918
Flesh out demo script
ezynda3 Aug 26, 2024
f582cbc
Finish demo script
ezynda3 Aug 27, 2024
9785369
Cleanup and comments
ezynda3 Aug 27, 2024
4cd03e0
Fix log
ezynda3 Aug 27, 2024
f18dab6
Remove extra files
ezynda3 Aug 27, 2024
0eaa7c8
Remove extra remapping
ezynda3 Aug 27, 2024
a3e6f5d
Remove unneeded lib
ezynda3 Aug 27, 2024
cfd1977
Add official Permit2 addresses
ezynda3 Aug 27, 2024
db2f0ff
Merge branch 'main' into gasless-revisited
ezynda3 Aug 28, 2024
e7395b2
Allow only signer to call using EIP2612
ezynda3 Aug 29, 2024
8364ac7
Merge branch 'gasless-revisited' of github.com:lifinance/contracts in…
ezynda3 Aug 29, 2024
5d772b0
Bind Permit2Proxy to a single diamond
ezynda3 Aug 29, 2024
2f8e953
Update deploy script
ezynda3 Aug 29, 2024
3d39c31
Implement non-gasless Permit2 flow
ezynda3 Aug 29, 2024
af38e51
Redeploy to staging and update demo script
ezynda3 Aug 29, 2024
056a8c2
Update comments and remove unneeded events/errors
ezynda3 Aug 30, 2024
1755f86
Add utility methods for determining the next valid nonce
ezynda3 Aug 30, 2024
17e5da3
Redeploy and update demo script
ezynda3 Aug 30, 2024
476ba04
Add documentation
ezynda3 Aug 30, 2024
10b6204
Fixes
ezynda3 Sep 2, 2024
f5f566d
Change witness type to be consistent with the rest of the codebase
ezynda3 Sep 3, 2024
be50801
Remove unneeded whitelist
ezynda3 Sep 3, 2024
e40f49a
Merge branch 'main' of github.com:lifinance/contracts into gasless-re…
0xDEnYO Sep 6, 2024
2202a50
test
0xDEnYO Sep 6, 2024
6f86400
test
0xDEnYO Sep 6, 2024
1aa3287
test
0xDEnYO Sep 6, 2024
c75b982
test
0xDEnYO Sep 6, 2024
b27f938
test
0xDEnYO Sep 6, 2024
26fa4ea
test
0xDEnYO Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Bind Permit2Proxy to a single diamond
  • Loading branch information
ezynda3 committed Aug 29, 2024
commit 5d772b0a79052e77fb646f4ef998e66aacc3ab43
61 changes: 12 additions & 49 deletions src/Periphery/Permit2Proxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC2
/// @notice Proxy contract allowing gasless (Permit2-enabled) calls to our
/// diamond contract
/// @custom:version 1.0.0
contract Permit2Proxy is TransferrableOwnership {
contract Permit2Proxy {
/// Storage ///

address public immutable LIFI_DIAMOND;
ISignatureTransfer public immutable PERMIT2;
mapping(address => bool) public diamondWhitelist;

Expand Down Expand Up @@ -47,10 +48,8 @@ contract Permit2Proxy is TransferrableOwnership {

/// Constructor ///

constructor(
address _owner,
ISignatureTransfer _permit2
) TransferrableOwnership(_owner) {
constructor(address _lifiDiamond, ISignatureTransfer _permit2) {
LIFI_DIAMOND = _lifiDiamond;
PERMIT2 = _permit2;

PERMIT_WITH_WITNESS_TYPEHASH = keccak256(
Expand All @@ -73,7 +72,6 @@ contract Permit2Proxy is TransferrableOwnership {
/// @param v User signature (recovery ID)
/// @param r User signature (ECDSA output)
/// @param s User signature (ECDSA output)
/// @param diamondAddress Address of the token to be bridged
/// @param diamondCalldata Address of the token to be bridged
function callDiamondWithEIP2612Signature(
address tokenAddress,
Expand All @@ -82,7 +80,6 @@ contract Permit2Proxy is TransferrableOwnership {
uint8 v,
bytes32 r,
bytes32 s,
address diamondAddress,
bytes calldata diamondCalldata
) public payable {
// call permit on token contract to register approval using signature
Expand All @@ -105,29 +102,27 @@ contract Permit2Proxy is TransferrableOwnership {
);

// maxApprove token to diamond if current allowance is insufficient
LibAsset.maxApproveERC20(IERC20(tokenAddress), diamondAddress, amount);
LibAsset.maxApproveERC20(IERC20(tokenAddress), LIFI_DIAMOND, amount);

// call our diamond to execute calldata
_executeCalldata(diamondAddress, diamondCalldata);
_executeCalldata(diamondCalldata);
}

/// @notice Allows to bridge tokens of one type through a LI.FI diamond
/// contract using Uniswap's Permit2 contract and a user signature
/// that verifies allowance, diamondAddress and diamondCalldata
/// @param _diamondAddress the diamond contract to execute the call
/// @param _diamondCalldata the calldata to execute
/// @param _signer the signer giving permission to transfer tokens
/// @param _permit the Uniswap Permit2 parameters
/// @param _signature the signature giving approval to transfer tokens
function callDiamondWithPermit2SignatureSingle(
address _diamondAddress,
bytes calldata _diamondCalldata,
address _signer,
ISignatureTransfer.PermitTransferFrom calldata _permit,
bytes calldata _signature
) external payable {
LIFICall memory lifiCall = LIFICall(
_diamondAddress,
LIFI_DIAMOND,
keccak256(_diamondCalldata)
);

Expand All @@ -148,43 +143,20 @@ contract Permit2Proxy is TransferrableOwnership {
// maxApprove token to diamond if current allowance is insufficient
LibAsset.maxApproveERC20(
IERC20(_permit.permitted.token),
_diamondAddress,
LIFI_DIAMOND,
_permit.permitted.amount
);

_executeCalldata(_diamondAddress, _diamondCalldata);
}

/// @notice Allows to update the whitelist of diamond contracts
/// @dev Admin function
/// @param addresses Addresses to be added (true) or removed (false) from
/// whitelist
/// @param values Values for each address that should be updated
function updateWhitelist(
address[] calldata addresses,
bool[] calldata values
) external onlyOwner {
for (uint i; i < addresses.length; ) {
// update whitelist address value
diamondWhitelist[addresses[i]] = values[i];

// gas-efficient way to increase the loop counter
unchecked {
++i;
}
}
emit WhitelistUpdated(addresses, values);
_executeCalldata(_diamondCalldata);
}

/// @notice utitlity method for constructing a valid Permit2 message hash
/// @param _diamondAddress the diamond address to call
/// @param _diamondCalldata the calldata to execute
/// @param _assetId the address of the token to approve
/// @param _amount amount of tokens to approve
/// @param _nonce the nonce to use
/// @param _deadline the expiration deadline
function getPermit2MsgHash(
address _diamondAddress,
bytes calldata _diamondCalldata,
address _assetId,
uint256 _amount,
Expand All @@ -201,7 +173,7 @@ contract Permit2Proxy is TransferrableOwnership {

// Witness
Permit2Proxy.LIFICall memory lifiCall = LIFICall(
_diamondAddress,
LIFI_DIAMOND,
keccak256(_diamondCalldata)
);
bytes32 witness = _getWitnessHash(lifiCall);
Expand Down Expand Up @@ -261,19 +233,10 @@ contract Permit2Proxy is TransferrableOwnership {
keccak256(abi.encodePacked("\x19\x01", domainSeparator, dataHash));
}

function _executeCalldata(
address diamondAddress,
bytes memory diamondCalldata
) internal {
// make sure diamondAddress is whitelisted
// this limits the usage of this Permit2Proxy contracts to only work
// with our diamond contracts
if (!diamondWhitelist[diamondAddress])
revert DiamondAddressNotWhitelisted();

function _executeCalldata(bytes memory diamondCalldata) internal {
// call diamond with provided calldata
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory data) = diamondAddress.call{
(bool success, bytes memory data) = LIFI_DIAMOND.call{
value: msg.value
}(diamondCalldata);
// throw error to make sure tx reverts if low-level call was
Expand Down
70 changes: 1 addition & 69 deletions test/solidity/Periphery/Permit2Proxy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,14 @@ contract Permit2ProxyTest is TestBase {
initTestBase();

uniPermit2 = ISignatureTransfer(PERMIT2_ADDRESS);
permit2Proxy = new Permit2Proxy(address(this), uniPermit2);
permit2Proxy = new Permit2Proxy(DIAMOND_ADDRESS, uniPermit2);
PERMIT_WITH_WITNESS_TYPEHASH = keccak256(
abi.encodePacked(
PermitHash._PERMIT_TRANSFER_FROM_WITNESS_TYPEHASH_STUB,
permit2Proxy.WITNESS_TYPE_STRING()
)
);

address[] memory whitelist = new address[](1);
whitelist[0] = DIAMOND_ADDRESS;
bool[] memory allowed = new bool[](1);
allowed[0] = true;
permit2Proxy.updateWhitelist(whitelist, allowed);
PERMIT2_USER = vm.addr(PRIVATE_KEY);
vm.label(PERMIT2_USER, "Permit2 User");
deal(ADDRESS_USDC, PERMIT2_USER, 10000 ether);
Expand Down Expand Up @@ -102,7 +97,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v,
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand Down Expand Up @@ -130,7 +124,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v,
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand All @@ -143,7 +136,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v,
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand Down Expand Up @@ -174,7 +166,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v,
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand Down Expand Up @@ -205,7 +196,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v + 1, // invalid v value
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand Down Expand Up @@ -235,7 +225,6 @@ contract Permit2ProxyTest is TestBase {
testdata.v,
testdata.r,
testdata.s,
DIAMOND_ADDRESS,
testdata.diamondCalldata
);

Expand All @@ -257,7 +246,6 @@ contract Permit2ProxyTest is TestBase {

// Execute
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
Expand All @@ -271,7 +259,6 @@ contract Permit2ProxyTest is TestBase {
(, , msgHash, ) = _getPermitWitnessTransferFromParams();

generatedMsgHash = permit2Proxy.getPermit2MsgHash(
DIAMOND_ADDRESS,
_getCalldataForBridging(),
ADDRESS_USDC,
defaultUSDCAmount,
Expand All @@ -282,29 +269,6 @@ contract Permit2ProxyTest is TestBase {
assertEq(msgHash, generatedMsgHash);
}

function testRevery_cannot_call_unwhitelisted_diamond() public {
DIAMOND_ADDRESS = address(0x11f1); // Not whitelisted
bytes memory diamondCalldata;
ISignatureTransfer.PermitTransferFrom memory permitTransferFrom;
bytes memory signature;
(
diamondCalldata,
permitTransferFrom,
,
signature
) = _getPermitWitnessTransferFromParams();

// Execute
vm.expectRevert(DiamondAddressNotWhitelisted.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
signature
);
}

function testRevert_cannot_call_diamond_single_with_same_signature_more_than_once()
public
{
Expand All @@ -321,42 +285,13 @@ contract Permit2ProxyTest is TestBase {

// Execute x2
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
signature
);
vm.expectRevert(InvalidNonce.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
signature
);
}

function testRevert_cannot_set_different_diamond_address_than_intended()
public
{
deal(ADDRESS_USDC, PERMIT2_USER, 10000 ether);
bytes memory diamondCalldata;
ISignatureTransfer.PermitTransferFrom memory permitTransferFrom;
bytes memory signature;
(
diamondCalldata,
permitTransferFrom,
,
signature
) = _getPermitWitnessTransferFromParams();

address MALICIOUS_CONTRACT;

// Execute
vm.expectRevert(InvalidSigner.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
MALICIOUS_CONTRACT,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
Expand All @@ -381,7 +316,6 @@ contract Permit2ProxyTest is TestBase {
// Execute
vm.expectRevert(InvalidSigner.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
MALICIOUS_CALLDATA,
PERMIT2_USER,
permitTransferFrom,
Expand All @@ -406,7 +340,6 @@ contract Permit2ProxyTest is TestBase {
// Execute
vm.expectRevert(InvalidSigner.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
Expand All @@ -433,7 +366,6 @@ contract Permit2ProxyTest is TestBase {
// Execute
vm.expectRevert(InvalidSigner.selector);
permit2Proxy.callDiamondWithPermit2SignatureSingle(
DIAMOND_ADDRESS,
diamondCalldata,
PERMIT2_USER,
permitTransferFrom,
Expand Down
Loading