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

Acrossv3 hotfix [AcrossFacetPackedV3 v1.2.0,ReceiverAcrossV3 v1.0.1] #897

Merged
merged 18 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ jobs:
run: |
cd lifi-contract-types
TMP=$(mktemp)
jq '.version="${NEW_VERSION}"' package.json > "$TMP" && mv "$TMP" package.json
jq --arg new_ver "$NEW_VERSION" '.version=$new_ver' package.json > "$TMP" && mv "$TMP" package.json
git config user.name github-actions
git config user.email [email protected]
echo "Updating version from $LATEST_TAG to $NEW_VERSION"
Expand Down
38 changes: 31 additions & 7 deletions deployments/_deployments_log_file.json
Original file line number Diff line number Diff line change
Expand Up @@ -24645,12 +24645,12 @@
"staging": {
"1.0.0": [
{
"ADDRESS": "0x3877f47B560819E96BBD7e7700a02dfACe36D696",
"ADDRESS": "0xe4F3DEF14D61e47c696374453CD64d438FD277F8",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-07-31 16:59:18",
"TIMESTAMP": "2024-12-06 12:41:24",
"CONSTRUCTOR_ARGS": "0x000000000000000000000000156cebba59deb2cb23742f70dcb0a11cc775591f00000000000000000000000023f882ba2fa54a358d8599465eb471f58cc26751000000000000000000000000e35e9842fceaca96570b734083f4a58e8f7c5f2a00000000000000000000000000000000000000000000000000000000000186a0",
"SALT": "31072024",
"VERIFIED": "false"
"SALT": "",
"VERIFIED": "true"
}
]
},
Expand Down Expand Up @@ -24707,6 +24707,18 @@
"VERIFIED": "true"
}
]
},
"staging": {
"1.0.0": [
{
"ADDRESS": "0xe4F3DEF14D61e47c696374453CD64d438FD277F8",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-12-06 12:40:08",
"CONSTRUCTOR_ARGS": "0x000000000000000000000000156cebba59deb2cb23742f70dcb0a11cc775591f00000000000000000000000023f882ba2fa54a358d8599465eb471f58cc267510000000000000000000000009295ee1d8c5b022be115a2ad3c30c72e34e7f09600000000000000000000000000000000000000000000000000000000000186a0",
"SALT": "",
"VERIFIED": "true"
}
]
}
},
"blast": {
Expand Down Expand Up @@ -24872,6 +24884,18 @@
"VERIFIED": "true"
}
]
},
"staging": {
"1.0.0": [
{
"ADDRESS": "0x21767081Ff52CE5563A29f27149D01C7127775A2",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-12-06 12:34:11",
"CONSTRUCTOR_ARGS": "0x0000000000000000000000009295ee1d8c5b022be115a2ad3c30c72e34e7f0960000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f619000000000000000000000000b9c0de368bece5e76b52545a8e377a4c118f597b",
"SALT": "",
"VERIFIED": "true"
}
]
}
},
"base": {
Expand Down Expand Up @@ -24904,9 +24928,9 @@
"staging": {
"1.0.0": [
{
"ADDRESS": "0x4352459F6BE1C7D1278F8c34Bb598b0feeB50f8b",
"ADDRESS": "0x21767081Ff52CE5563A29f27149D01C7127775A2",
"OPTIMIZER_RUNS": "1000000",
"TIMESTAMP": "2024-10-03 07:44:55",
"TIMESTAMP": "2024-12-06 12:24:22",
"CONSTRUCTOR_ARGS": "0x000000000000000000000000e35e9842fceaca96570b734083f4a58e8f7c5f2a00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1000000000000000000000000b9c0de368bece5e76b52545a8e377a4c118f597b",
"SALT": "",
"VERIFIED": "true"
Expand Down Expand Up @@ -25749,4 +25773,4 @@
}
}
}
}
}
6 changes: 3 additions & 3 deletions deployments/arbitrum.staging.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@
"EmergencyPauseFacet": "0x17Bb203F42d8e404ac7E8dB6ff972B7E8473850b",
"Permit2Proxy": "0x6FC01BC9Ff6Cdab694Ec8Ca41B21a2F04C8c37E5",
"AcrossFacetV3": "0x6124C65B6264bE13f059b7C3A891a5b77DA8Bd95",
"ReceiverAcrossV3": "0x3877f47B560819E96BBD7e7700a02dfACe36D696",
"AcrossFacetPackedV3": "0x4352459F6BE1C7D1278F8c34Bb598b0feeB50f8b"
}
"ReceiverAcrossV3": "0xe4F3DEF14D61e47c696374453CD64d438FD277F8",
"AcrossFacetPackedV3": "0x21767081Ff52CE5563A29f27149D01C7127775A2"
}
6 changes: 4 additions & 2 deletions deployments/polygon.staging.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,7 @@
"HopFacetOptimized": "0xf82135385765f1324257ffF74489F16382EBBb8A",
"SymbiosisFacet": "0x21571D628B0bCBeb954D5933A604eCac35bAF2c7",
"AcrossFacetV3": "0xe2e5428F972d9C0a5Ba433e0c402752b472dB248",
"Permit2Proxy": "0x6FC01BC9Ff6Cdab694Ec8Ca41B21a2F04C8c37E5"
}
"Permit2Proxy": "0x6FC01BC9Ff6Cdab694Ec8Ca41B21a2F04C8c37E5",
"AcrossFacetPackedV3": "0x21767081Ff52CE5563A29f27149D01C7127775A2",
"ReceiverAcrossV3": "0xe4F3DEF14D61e47c696374453CD64d438FD277F8"
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
}
175 changes: 103 additions & 72 deletions src/Facets/AcrossFacetPackedV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { LibAsset, IERC20 } from "../Libraries/LibAsset.sol";
/// @title AcrossFacetPackedV3
/// @author LI.FI (https://li.fi)
/// @notice Provides functionality for bridging through Across in a gas-optimized way
/// @custom:version 1.0.0
/// @custom:version 1.2.0
contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
using SafeTransferLib for ERC20;

Expand All @@ -37,6 +37,7 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
struct PackedParameters {
bytes32 transactionId;
address receiver;
address depositor;
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
uint64 destinationChainId;
address receivingAssetId;
uint256 outputAmount;
Expand Down Expand Up @@ -81,22 +82,34 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
}

/// @notice Bridges native tokens via Across (packed implementation)
/// No params, all data will be extracted from manually encoded callData
/// @dev Calldata mapping:
/// [0:4] - function selector
/// [4:12] - transactionId
/// [12:32] - receiver
/// [32:52] - depositor
/// [52:56] - destinationChainId
/// [56:76] - receivingAssetId
/// [76:108] - outputAmount
/// [108:128] - exclusiveRelayer
/// [128:132] - quoteTimestamp
/// [132:136] - fillDeadline
/// [136:140] - exclusivityDeadline
/// [140:] - message
ezynda3 marked this conversation as resolved.
Show resolved Hide resolved
function startBridgeTokensViaAcrossV3NativePacked() external payable {
// call Across spoke pool to bridge assets
spokePool.depositV3{ value: msg.value }(
msg.sender, // depositor
address(bytes20(msg.data[32:52])), // depositor
address(bytes20(msg.data[12:32])), // recipient
wrappedNative, // inputToken
address(bytes20(msg.data[36:56])), // outputToken
address(bytes20(msg.data[56:76])), // outputToken
msg.value, // inputAmount
uint256(bytes32(msg.data[56:88])), // outputAmount
uint64(uint32(bytes4(msg.data[32:36]))), // destinationChainId
address(bytes20(msg.data[88:108])), // exclusiveRelayer
uint32(bytes4(msg.data[108:112])), // quoteTimestamp
uint32(bytes4(msg.data[112:116])), // fillDeadline
uint32(bytes4(msg.data[116:120])), // exclusivityDeadline
msg.data[120:msg.data.length]
uint256(bytes32(msg.data[76:108])), // outputAmount
uint64(uint32(bytes4(msg.data[52:56]))), // destinationChainId
address(bytes20(msg.data[108:128])), // exclusiveRelayer
uint32(bytes4(msg.data[128:132])), // quoteTimestamp
uint32(bytes4(msg.data[132:136])), // fillDeadline
uint32(bytes4(msg.data[136:140])), // exclusivityDeadline
msg.data[140:msg.data.length]
);

emit LiFiAcrossTransfer(bytes8(msg.data[4:12]));
Expand Down Expand Up @@ -127,32 +140,44 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
}

/// @notice Bridges ERC20 tokens via Across (packed implementation)
/// No params, all data will be extracted from manually encoded callData
/// @dev Calldata mapping:
/// [0:4] - function selector
/// [4:12] - transactionId
/// [12:32] - receiver
/// [32:52] - depositor
/// [52:72] - sendingAssetId
/// [72:88] - inputAmount
/// [88:92] - destinationChainId
/// [92:112] - receivingAssetId
/// [112:144] - outputAmount
/// [144:164] - exclusiveRelayer
/// [164:168] - quoteTimestamp
/// [168:172] - fillDeadline
/// [172:176] - exclusivityDeadline
/// [176:] - message
function startBridgeTokensViaAcrossV3ERC20Packed() external {
address sendingAssetId = address(bytes20(msg.data[32:52]));
uint256 inputAmount = uint256(uint128(bytes16(msg.data[52:68])));
address sendingAssetId = address(bytes20(msg.data[52:72]));
uint256 inputAmount = uint256(uint128(bytes16(msg.data[72:88])));

// Deposit assets
ERC20(sendingAssetId).safeTransferFrom(
msg.sender,
address(this),
inputAmount
);

// call Across SpokePool
spokePool.depositV3(
msg.sender, // depositor
address(bytes20(msg.data[32:52])), // depositor
address(bytes20(msg.data[12:32])), // recipient
sendingAssetId, // inputToken
address(bytes20(msg.data[72:92])), // outputToken
address(bytes20(msg.data[92:112])), // outputToken
inputAmount, // inputAmount
uint256(bytes32(msg.data[92:124])), // outputAmount
uint64(uint32(bytes4(msg.data[68:72]))), // destinationChainId
address(bytes20(msg.data[124:144])), // exclusiveRelayer
uint32(bytes4(msg.data[144:148])), // quoteTimestamp
uint32(bytes4(msg.data[148:152])), // fillDeadline
uint32(bytes4(msg.data[152:156])), // exclusivityDeadline
msg.data[156:msg.data.length]
uint256(bytes32(msg.data[112:144])), // outputAmount
uint64(uint32(bytes4(msg.data[88:92]))), // destinationChainId
address(bytes20(msg.data[144:164])), // exclusiveRelayer
uint32(bytes4(msg.data[164:168])), // quoteTimestamp
uint32(bytes4(msg.data[168:172])), // fillDeadline
uint32(bytes4(msg.data[172:176])), // exclusivityDeadline
msg.data[176:msg.data.length]
);

emit LiFiAcrossTransfer(bytes8(msg.data[4:12]));
Expand Down Expand Up @@ -198,8 +223,6 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
function encode_startBridgeTokensViaAcrossV3NativePacked(
PackedParameters calldata _parameters
) external pure returns (bytes memory) {
// there are already existing networks with chainIds outside uint32 range but since we not support either of them yet,
// we feel comfortable using this approach to save further gas
require(
_parameters.destinationChainId <= type(uint32).max,
"destinationChainId value passed too big to fit in uint32"
Expand All @@ -212,6 +235,7 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
.selector,
bytes8(_parameters.transactionId),
bytes20(_parameters.receiver),
bytes20(_parameters.depositor),
bytes4(uint32(_parameters.destinationChainId)),
bytes20(_parameters.receivingAssetId),
bytes32(_parameters.outputAmount),
Expand All @@ -232,8 +256,6 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
address sendingAssetId,
uint256 inputAmount
) external pure returns (bytes memory) {
// there are already existing networks with chainIds outside uint32 range but since we not support either of them yet,
// we feel comfortable using this approach to save further gas
require(
_parameters.destinationChainId <= type(uint32).max,
"destinationChainId value passed too big to fit in uint32"
Expand All @@ -244,24 +266,33 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
"inputAmount value passed too big to fit in uint128"
);

return
bytes.concat(
AcrossFacetPackedV3
.startBridgeTokensViaAcrossV3ERC20Packed
.selector,
bytes8(_parameters.transactionId),
bytes20(_parameters.receiver),
bytes20(sendingAssetId),
bytes16(uint128(inputAmount)),
bytes4(uint32(_parameters.destinationChainId)),
bytes20(_parameters.receivingAssetId),
bytes32(_parameters.outputAmount),
bytes20(_parameters.exclusiveRelayer),
bytes4(_parameters.quoteTimestamp),
bytes4(_parameters.fillDeadline),
bytes4(_parameters.exclusivityDeadline),
_parameters.message
);
// Split the concatenation into parts to avoid "stack too deep" errors
bytes memory part1 = bytes.concat(
AcrossFacetPackedV3
.startBridgeTokensViaAcrossV3ERC20Packed
.selector,
bytes8(_parameters.transactionId),
bytes20(_parameters.receiver),
bytes20(_parameters.depositor),
bytes20(sendingAssetId)
);

bytes memory part2 = bytes.concat(
bytes16(uint128(inputAmount)),
bytes4(uint32(_parameters.destinationChainId)),
bytes20(_parameters.receivingAssetId),
bytes32(_parameters.outputAmount)
);

bytes memory part3 = bytes.concat(
bytes20(_parameters.exclusiveRelayer),
bytes4(_parameters.quoteTimestamp),
bytes4(_parameters.fillDeadline),
bytes4(_parameters.exclusivityDeadline)
);

// Combine all parts with the message
return bytes.concat(part1, part2, part3, _parameters.message);
}

/// @notice Decodes calldata that is meant to be used for calling the native 'packed' function
Expand All @@ -277,23 +308,24 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
)
{
require(
data.length >= 120,
"invalid calldata (must have length >= 120)"
data.length >= 140,
"invalid calldata (must have length >= 140)"
);

// extract bridgeData
bridgeData.transactionId = bytes32(bytes8(data[4:12]));
bridgeData.receiver = address(bytes20(data[12:32]));
bridgeData.destinationChainId = uint64(uint32(bytes4(data[32:36])));
bridgeData.destinationChainId = uint64(uint32(bytes4(data[52:56])));

// extract acrossData
acrossData.receivingAssetId = address(bytes20(data[36:56]));
acrossData.outputAmount = uint256(bytes32(data[56:88]));
acrossData.exclusiveRelayer = address(bytes20(data[88:108]));
acrossData.quoteTimestamp = uint32(bytes4(data[108:112]));
acrossData.fillDeadline = uint32(bytes4(data[112:116]));
acrossData.exclusivityDeadline = uint32(bytes4(data[116:120]));
acrossData.message = data[120:];
acrossData.refundAddress = address(bytes20(data[32:52])); // depositor
acrossData.receivingAssetId = address(bytes20(data[56:76]));
acrossData.outputAmount = uint256(bytes32(data[76:108]));
acrossData.exclusiveRelayer = address(bytes20(data[108:128]));
acrossData.quoteTimestamp = uint32(bytes4(data[128:132]));
acrossData.fillDeadline = uint32(bytes4(data[132:136]));
acrossData.exclusivityDeadline = uint32(bytes4(data[136:140]));
acrossData.message = data[140:];

return (bridgeData, acrossData);
}
Expand All @@ -311,25 +343,24 @@ contract AcrossFacetPackedV3 is ILiFi, TransferrableOwnership {
)
{
require(
data.length >= 156,
"invalid calldata (must have length > 156)"
data.length >= 176,
"invalid calldata (must have length >= 176)"
);

// extract bridgeData
bridgeData.transactionId = bytes32(bytes8(data[4:12]));
bridgeData.receiver = address(bytes20(data[12:32]));
bridgeData.sendingAssetId = address(bytes20(data[32:52]));
bridgeData.minAmount = uint256(uint128(bytes16(data[52:68])));
bridgeData.destinationChainId = uint64(uint32(bytes4(data[68:72])));

// extract acrossData
acrossData.receivingAssetId = address(bytes20(data[72:92]));
acrossData.outputAmount = uint256(bytes32(data[92:124]));
acrossData.exclusiveRelayer = address(bytes20(data[124:144]));
acrossData.quoteTimestamp = uint32(bytes4(data[144:148]));
acrossData.fillDeadline = uint32(bytes4(data[148:152]));
acrossData.exclusivityDeadline = uint32(bytes4(data[152:156]));
acrossData.message = data[156:];
acrossData.refundAddress = address(bytes20(data[32:52])); // depositor
bridgeData.sendingAssetId = address(bytes20(data[52:72]));
bridgeData.minAmount = uint256(uint128(bytes16(data[72:88])));
bridgeData.destinationChainId = uint64(uint32(bytes4(data[88:92])));

acrossData.receivingAssetId = address(bytes20(data[92:112]));
acrossData.outputAmount = uint256(bytes32(data[112:144]));
acrossData.exclusiveRelayer = address(bytes20(data[144:164]));
acrossData.quoteTimestamp = uint32(bytes4(data[164:168]));
acrossData.fillDeadline = uint32(bytes4(data[168:172]));
acrossData.exclusivityDeadline = uint32(bytes4(data[172:176]));
acrossData.message = data[176:];

return (bridgeData, acrossData);
}
Expand Down
Loading
Loading