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

fix: adapter blast #52

Merged
merged 6 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
50 changes: 50 additions & 0 deletions broadcast/DeployLockboxAdapterBlast.s.sol/1/run-latest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"transactions": [
{
"hash": "0xb2647531460473ecf20dd845c9e8256d1fefbec11c9b5947c5cfaf76b907364a",
"transactionType": "CREATE",
"contractName": "LockboxAdapterBlast",
"contractAddress": "0xBE1a8Fe5CB3B7E50825Cef73aFDf29E3fc34DE33",
"function": null,
"arguments": [
"0x697402166Fbf2F22E970df8a6486Ef171dbfc524",
"0xBf29A2D67eFb6766E44c163B19C6F4118b164702"
],
"transaction": {
"type": "0x02",
"from": "0xade09131c6f43fe22c2cbabb759636c43cfc181e",
"gas": "0xa6de5",
"value": "0x0",
"data": "0x60c0346100b757601f61096238819003918201601f19168301916001600160401b038311848410176100bc5780849260409485528339810103126100b757610052602061004b836100d2565b92016100d2565b906001600160a01b03808216159081156100ac575b5061009a5760805260a05260405161087b90816100e7823960805181610273015260a051818181610102015261015c0152f35b60405163e6c4247b60e01b8152600490fd5b905082161538610067565b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036100b75756fe608080604052600436101561001357600080fd5b6000803560e01c63636626f11461002957600080fd5b346103705760c0366003190112610370576004356001600160a01b038116810361046f57602435926001600160a01b038416840361046b57604435916001600160a01b0383168303610467576084359163ffffffff831683036104635767ffffffffffffffff60a435116104635736602360a4350112156104635767ffffffffffffffff60a43560040135116104635736602460a4356004013560a4350101116104635760643515610454575060405163476a536360e11b81526001600160a01b038681166004830152909190602090839060249082907f0000000000000000000000000000000000000000000000000000000000000000165afa918215610396578592610433575b5060405163eec9567960e01b81526001600160a01b038381166004830152602090829060249082907f0000000000000000000000000000000000000000000000000000000000000000165afa9081156104285786916103f9575b506001600160a01b0383161580156103e8575b6103d6576001600160a01b03858116908416036103b5576040516323b872dd60e01b60208201523360248201523060448201526064803581830152815260a0810167ffffffffffffffff8111828210176103a157604052959687966102269190610212906001600160a01b03831661062c565b6064359083906001600160a01b03166104e3565b6001600160a01b0381163b1561037e5760405163b6b55f2560e01b8152606435600482015296869188916024918391906001600160a01b03165af1801561039657610382575b93945084937f00000000000000000000000000000000000000000000000000000000000000006102a8606435826001600160a01b0386166104e3565b6001600160a01b031690813b1561037e57859363ffffffff9160405196879563540abf7360e01b875260018060a01b0316600487015260018060a01b0316602486015260018060a01b03166044850152606435606485015216608483015260c060a483015260a4356004013560c483015260a43560040135602460a4350160e48401378260e460a4356004013584010152818360e482601f19601f60a43560040135011681010301925af18015610373576103605750f35b61036990610473565b6103705780f35b80fd5b6040513d84823e3d90fd5b8580fd5b93909461038e90610473565b92849061026c565b6040513d87823e3d90fd5b634e487b7160e01b88526041600452602488fd5b60405163359ff56f60e01b81526001600160a01b0386166004820152602490fd5b60405163e6c4247b60e01b8152600490fd5b506001600160a01b0381161561019f565b61041b915060203d602011610421575b610413818361049d565b8101906104bf565b3861018c565b503d610409565b6040513d88823e3d90fd5b61044d91925060203d60201161042157610413818361049d565b9038610132565b63820bf1e560e01b8152600490fd5b8480fd5b8380fd5b8280fd5b5080fd5b67ffffffffffffffff811161048757604052565b634e487b7160e01b600052604160045260246000fd5b90601f8019910116810190811067ffffffffffffffff82111761048757604052565b908160209103126104de57516001600160a01b03811681036104de5790565b600080fd5b91801580156105a7575b156105435760405163095ea7b360e01b60208201526001600160a01b0390921660248301526044808301919091528152608081019167ffffffffffffffff831182841017610487576105419260405261062c565b565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608490fd5b50604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526020908290604490829088165afa908115610620576000916105ef575b50156104ed565b906020823d8211610618575b816106086020938361049d565b81010312610370575051386105e8565b3d91506105fb565b6040513d6000823e3d90fd5b60018060a01b0316906040516040810167ffffffffffffffff9082811082821117610487576040526020938483527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564858401526000808587829751910182855af1903d15610766573d92831161075257906106c7939291604051926106ba88601f19601f840116018561049d565b83523d868885013e610771565b8051806106d5575b50505050565b8184918101031261046f578201519081159182150361037057506106fb578080806106cf565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b634e487b7160e01b85526041600452602485fd5b906106c79392506060915b919290156107d35750815115610785575090565b3b1561078e5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156107e65750805190602001fd5b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b82851061082c575050604492506000838284010152601f80199101168101030190fd5b848101820151868601604401529381019385935061080956fea2646970667358221220ccb5894e7ee5d863bbdcb36e2ce6551aebeed85599ea3c6c477c272f4a0713ec64736f6c63430008140033000000000000000000000000697402166fbf2f22e970df8a6486ef171dbfc524000000000000000000000000bf29a2d67efb6766e44c163b19c6f4118b164702",
"nonce": "0x7e9",
"accessList": []
},
"additionalContracts": [],
"isFixedGasLimit": false
}
],
"receipts": [
{
"transactionHash": "0xb2647531460473ecf20dd845c9e8256d1fefbec11c9b5947c5cfaf76b907364a",
"transactionIndex": "0x6",
"blockHash": "0xb11507aa58fed7d0cf00e557a5602647ea73532ab2a78f5eaa5937409ddf455c",
"blockNumber": "0x129f710",
"from": "0xade09131C6f43fe22C2CbABb759636C43cFc181e",
"to": null,
"cumulativeGasUsed": "0x1896e9",
"gasUsed": "0x80660",
"contractAddress": "0xBE1a8Fe5CB3B7E50825Cef73aFDf29E3fc34DE33",
"logs": [],
"status": "0x1",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"type": "0x2",
"effectiveGasPrice": "0xe4d8b75bf"
}
],
"libraries": [],
"pending": [],
"returns": {},
"timestamp": 1711564889,
"chain": 1,
"commit": "c53bb2b"
}
2 changes: 1 addition & 1 deletion contracts/integration/LockboxAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,4 @@ contract LockboxAdapter is IXReceiver {
}

receive() external payable {}
}
}
124 changes: 75 additions & 49 deletions contracts/integration/LockboxAdapterBlast.sol
Original file line number Diff line number Diff line change
@@ -1,70 +1,96 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IXERC20} from "../shared/IXERC20/IXERC20.sol";
import {IXERC20Lockbox} from "../shared/IXERC20/IXERC20Lockbox.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IXERC20 } from "../shared/IXERC20/IXERC20.sol";
import { IXERC20Lockbox } from "../shared/IXERC20/IXERC20Lockbox.sol";

interface IXERC20Registry {
function getXERC20(address erc20) external view returns (address xerc20);
function getXERC20(address erc20) external view returns (address xerc20);

function getERC20(address xerc20) external view returns (address erc20);
function getERC20(address xerc20) external view returns (address erc20);

function getLockbox(address erc20) external view returns (address xerc20);
function getLockbox(address erc20) external view returns (address xerc20);
}

interface L1StandardBridge {
function bridgeERC20To(
address _localToken,
address _remoteToken,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external;
function bridgeERC20To(
address _localToken,
address _remoteToken,
address _to,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external;
}

/// @notice This adapter is only used for sending assets from Ethereum mainnet to Blast.
/// @dev Combines Lockbox deposit and Blast bridge's BridgeERC20 call.
/// @dev Combines Lockbox deposit and Blast bridge's BridgeERC20 call to minimize user transactions.
contract LockboxAdapterBlast {
address immutable blastStandardBridge;
address immutable registry;
address immutable blastStandardBridge;
address immutable registry;

// ERRORS
error AmountLessThanZero();
// ERRORS
error InvalidRemoteToken(address _remoteToken);
error AmountLessThanZero();
error InvalidAddress();

constructor(address _blastStandardBridge, address _registry) {
blastStandardBridge = _blastStandardBridge;
registry = _registry;
}
constructor(address _blastStandardBridge, address _registry) {
// Sanity check
if (_blastStandardBridge == address(0) || _registry == address(0)) {
revert InvalidAddress();
}

/// @dev Combines Lockbox deposit and Blast bridge's BridgeERC20To call.
/// @param _to The recipient or contract address on destination.
/// @param _erc20 The address of the adopted ERC20 on the origin chain.
/// @param _remoteToken The address of the asset to be received on the destination chain.
/// @param _amount The amount of asset to bridge.
/// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
/// @param _extraData Extra data to be sent with the transaction.
function bridgeTo(
address _to,
address _erc20,
address _remoteToken,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external {
if (_amount <= 0) {
revert AmountLessThanZero();
blastStandardBridge = _blastStandardBridge;
registry = _registry;
}

address xerc20 = IXERC20Registry(registry).getXERC20(_erc20);
address lockbox = IXERC20Registry(registry).getLockbox(xerc20);
/// @dev Combines Lockbox deposit and Blast bridge's BridgeERC20To call.
/// @param _to The recipient or contract address on destination.
/// @param _erc20 The address of the adopted ERC20 on the origin chain.
/// @param _remoteToken The address of the asset to be received on the destination chain.
/// @param _amount The amount of asset to bridge.
/// @param _minGasLimit Minimum amount of gas that the bridge can be relayed with.
/// @param _extraData Extra data to be sent with the transaction.
function bridgeTo(
address _to,
address _erc20,
address _remoteToken,
uint256 _amount,
uint32 _minGasLimit,
bytes calldata _extraData
) external {
// Sanity check
if (_amount <= 0) {
revert AmountLessThanZero();
}

SafeERC20.safeTransferFrom(IERC20(_erc20), msg.sender, address(this), _amount);
IERC20(_erc20).approve(lockbox, _amount);
IXERC20Lockbox(lockbox).deposit(_amount);
IERC20(xerc20).approve(blastStandardBridge, _amount);
L1StandardBridge(blastStandardBridge).bridgeERC20To(xerc20, _remoteToken, _to, _amount, _minGasLimit, _extraData);
}
address xerc20 = IXERC20Registry(registry).getXERC20(_erc20);
address lockbox = IXERC20Registry(registry).getLockbox(xerc20);

// Sanity check
if (xerc20 == address(0) || lockbox == address(0)) {
revert InvalidAddress();
}

// If using xERC20, the assumption is that the contract should be deployed at same address
// on both networks.
if (xerc20 != _remoteToken) {
revert InvalidRemoteToken(_remoteToken);
}

SafeERC20.safeTransferFrom(IERC20(_erc20), msg.sender, address(this), _amount);
SafeERC20.safeApprove(IERC20(_erc20), lockbox, _amount);
IXERC20Lockbox(lockbox).deposit(_amount);
SafeERC20.safeApprove(IERC20(xerc20), blastStandardBridge, _amount);
L1StandardBridge(blastStandardBridge).bridgeERC20To(
xerc20,
_remoteToken,
_to,
_amount,
_minGasLimit,
_extraData
);
}
}
Loading