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

Dennis feedback #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SendParam, OFTReceipt, MessagingFee, IOFT } from "@fraxfinance/layerzer
import { OptionsBuilder } from "@fraxfinance/layerzero-v2-upgradeable/oapp/contracts/oapp/libs/OptionsBuilder.sol";

import { FraxtalConstants } from "src/contracts/FraxtalConstants.sol";
import { IL1Bridge } from "src/contracts/shared/IL1Bridge.sol";

// ====================================================================
// | ______ _______ |
Expand All @@ -20,20 +21,21 @@ import { FraxtalConstants } from "src/contracts/FraxtalConstants.sol";
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ======================= EthereumLZSenderAMO ========================
// ======================= EthereumLZCurveAMO ========================
// ====================================================================

/// @author Frax Finance: https://github.com/FraxFinance
contract EthereumLZSenderAMO is OwnableUpgradeable, FraxtalConstants {
contract EthereumLZCurveAMO is OwnableUpgradeable, FraxtalConstants {
using OptionsBuilder for bytes;

error FailedEthTransfer();

// keccak256(abi.encode(uint256(keccak256("frax.storage.EthereumLZSenderAMO")) - 1));
bytes32 private constant EthereumLZSenderAmoStorageLocation =
0xae71d745ae90af64f9f5e208d9e8dce64cca865b5246e2309de5b63cca6b882a;
// keccak256(abi.encode(uint256(keccak256("frax.storage.EthereumLZCurveAMO")) - 1));
bytes32 private constant EthereumLZCurveAmoStorageLocation =
0x9457c09651b1abd0043ec778e295270b24c7b02014c9a6e064fec36091d1f6ce;

struct EthereumLZSenderAmoStorage {
struct EthereumLZCurveAmoStorage {
address l1Bridge;
address fraxtalLzCurveAmo;
address fraxOft;
address sFraxOft;
Expand All @@ -42,9 +44,9 @@ contract EthereumLZSenderAMO is OwnableUpgradeable, FraxtalConstants {
address fpiOft;
}

function _getEthereumLZSenderAmoStorage() private pure returns (EthereumLZSenderAmoStorage storage $) {
function _getEthereumLZCurveAmoStorage() private pure returns (EthereumLZCurveAmoStorage storage $) {
assembly {
$.slot := EthereumLZSenderAmoStorageLocation
$.slot := EthereumLZCurveAmoStorageLocation
}
}

Expand All @@ -54,14 +56,16 @@ contract EthereumLZSenderAMO is OwnableUpgradeable, FraxtalConstants {

function initialize(
address _owner,
address _l1Bridge,
address _fraxtalLzCurveAmo,
address _fraxOft,
address _sFraxOft,
address _sFrxEthOft,
address _fxsOft,
address _fpiOft
) external initializer {
EthereumLZSenderAmoStorage storage $ = _getEthereumLZSenderAmoStorage();
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
$.l1Bridge = _l1Bridge;
$.fraxtalLzCurveAmo = _fraxtalLzCurveAmo;
$.fraxOft = _fraxOft;
$.sFraxOft = _sFraxOft;
Expand All @@ -72,23 +76,44 @@ contract EthereumLZSenderAMO is OwnableUpgradeable, FraxtalConstants {
_transferOwnership(_owner);
}

function sendAllToFraxtal() external {
EthereumLZSenderAmoStorage storage $ = _getEthereumLZSenderAmoStorage();
function _validateOft(address _oApp) internal view {
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
require(
_oApp == $.fraxOft ||
_oApp == $.sFraxOft ||
_oApp == $.sFrxEthOft ||
_oApp == $.fxsOft ||
_oApp == $.fpiOft,
"Invalid OFT"
);
}

sendToFraxtal($.fraxOft);
sendToFraxtal($.sFraxOft);
sendToFraxtal($.sFrxEthOft);
sendToFraxtal($.fxsOft);
sendToFraxtal($.fpiOft);
function _getL2Token(address _oApp) internal view returns (address) {
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
if (_oApp == $.fraxOft) {
return FraxtalConstants.frax;
} else if (_oApp == $.sFraxOft) {
return FraxtalConstants.sFrax;
} else if (_oApp == $.sFrxEthOft) {
return FraxtalConstants.sFrxEth;
} else if (_oApp == $.fxsOft) {
return FraxtalConstants.fxs;
} else {
/// @dev assume _oApp is one of these tokens as _validateOft is called prior and would revert
return FraxtalConstants.fpi;
}
}

function sendToFraxtal(address _oApp) internal {
function sendViaLz(address _oApp, uint256 _amount) external {
// reverts if invalid OFT
_validateOft(_oApp);

address token = IOFT(_oApp).token();
uint256 amount = IERC20(token).balanceOf(address(this));
if (amount == 0) return;

// craft tx
bytes memory options = OptionsBuilder.newOptions();
// round amount to prevent dust lost
uint256 amount = (_amount / 1e13) * 1e13;
SendParam memory sendParam = SendParam({
dstEid: uint32(30255), // fraxtal
to: bytes32(uint256(uint160(fraxtalLzCurveAmo()))),
Expand All @@ -105,13 +130,37 @@ contract EthereumLZSenderAMO is OwnableUpgradeable, FraxtalConstants {
IOFT(_oApp).send{ value: fee.nativeFee }(sendParam, fee, payable(address(this)));
}

function sendViaNativeBridge(address _oApp, uint256 _amount) external {
// reverts if invalid OFT
_validateOft(_oApp);

address token = IOFT(_oApp).token();

// approve and send
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
IERC20(token).approve($.l1Bridge, _amount);
IL1Bridge($.l1Bridge).depositERC20To({
_l1Token: token,
_l2Token: _getL2Token(_oApp),
_to: $.fraxtalLzCurveAmo,
_amount: _amount,
_minGasLimit: uint32(200_000),
_extraData: ""
});
}

function rescueEth(address to, uint256 amount) external payable onlyOwner {
(bool success, ) = to.call{ value: amount }("");
if (!success) revert FailedEthTransfer();
}

function fraxtalLzCurveAmo() public view returns (address) {
EthereumLZSenderAmoStorage storage $ = _getEthereumLZSenderAmoStorage();
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
return $.fraxtalLzCurveAmo;
}

function l1Bridge() public view returns (address) {
EthereumLZCurveAmoStorage storage $ = _getEthereumLZCurveAmoStorage();
return $.l1Bridge;
}
}
7 changes: 3 additions & 4 deletions src/contracts/amos/FraxtalLZCurveAMO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,22 @@ contract FraxtalLZCurveAMO is AccessControlUpgradeable, FraxtalConstants {
// TODO: now what
}

function sendToAdapterAndBridgeBackNatively(address _oApp, uint256 _amount) external onlyRole(SEND_ROLE) {
function sendViaLz(address _oApp, uint256 _amount) external onlyRole(SEND_ROLE) {
bytes memory options = OptionsBuilder.newOptions().addExecutorLzComposeOption(0, 100_000, 0);
bytes memory composeMsg = abi.encode(uint256(0));
SendParam memory sendParam = SendParam({
dstEid: uint32(30101), // Ethereum
to: bytes32(uint256(uint160(ethereumComposer()))),
amountLD: _amount,
minAmountLD: 0,
extraOptions: options,
composeMsg: composeMsg,
composeMsg: "",
oftCmd: ""
});
MessagingFee memory fee = IOFT(_oApp).quoteSend(sendParam, false);
IOFT(_oApp).send{ value: fee.nativeFee }(sendParam, fee, payable(address(this)));
}

function sendToFerry(address _oApp, uint256 _amount) external onlyRole(SEND_ROLE) {
function sendViaFerry(address _oApp, uint256 _amount) external onlyRole(SEND_ROLE) {
(address nToken, ) = _getRespectiveTokens(_oApp);
address ferry;
if (nToken == FraxtalL2.FRAX) {
Expand Down
123 changes: 0 additions & 123 deletions src/contracts/composers/EthereumNativeBridgeComposer.sol

This file was deleted.

22 changes: 6 additions & 16 deletions src/script/2DeployEthereum.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ pragma solidity ^0.8.19;

import { BaseScript } from "frax-std/BaseScript.sol";
import { console } from "frax-std/FraxTest.sol";
import { EthereumNativeBridgeComposer } from "../contracts/composers/EthereumNativeBridgeComposer.sol";
import { EthereumLZSenderAMO } from "../contracts/amos/EthereumLZSenderAMO.sol";
import { EthereumLZCurveAMO } from "../contracts/amos/EthereumLZCurveAMO.sol";
import { FraxProxy } from "../contracts/FraxProxy.sol";

// Run this with source .env && forge script --broadcast --rpc-url $MAINNET_URL DeployFraxtalL.s.sol
Expand All @@ -22,25 +21,16 @@ contract DeployFraxtalL is BaseScript {
address fpiOft = 0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d;

function run() public broadcaster {
// deploy EthereumNativeBridgeComposer
address implementation = address(new EthereumNativeBridgeComposer());
// Deploy EthereumLZCurveAMO
address implementation = address(new EthereumLZCurveAMO());
FraxProxy proxy = new FraxProxy(
implementation,
multisig,
abi.encodeCall(EthereumNativeBridgeComposer.initialize, (endpoint, l1Bridge, fraxtalLzCurveAmo))
);
console.log("EthereumNativeBridgeComposer @ ", address(proxy));

// Deploy EthereumLZSenderAMO
implementation = address(new EthereumLZSenderAMO());
proxy = new FraxProxy(
implementation,
multisig,
abi.encodeCall(
EthereumLZSenderAMO.initialize,
(deployer, fraxtalLzCurveAmo, fraxOft, sFraxOft, sFrxEthOft, fxsOft, fpiOft)
EthereumLZCurveAMO.initialize,
(deployer, l1Bridge, fraxtalLzCurveAmo, fraxOft, sFraxOft, sFrxEthOft, fxsOft, fpiOft)
)
);
console.log("EthereumLZSenderAMO @ ", address(proxy));
console.log("EthereumLZCurveAMO @ ", address(proxy));
}
}
Loading