-
Notifications
You must be signed in to change notification settings - Fork 0
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
V0.1.0 #5
V0.1.0 #5
Conversation
* deploy MockReceiver * feat: store sender * chore: fmt
* feat: unwrap frxEth * fix: outdated references * fix: receive ether * chore: fmt * chore: rm counter * chore: fmt * chore(build): comment out test
* feat: support all 6 OFTs * feat: support all 6 OFTs * feat: swapAndSend() * fix(swapAndSend): send ETH, refund extra, wrap frxETH * chore: fmt
|
||
// address oft = 0x909DBdE1eBE906Af95660033e478D59EFe831fED; // Base FRAX OFT | ||
address oft = 0xF010a7c8877043681D59AD125EbF575633505942; // Base frxETH OFT | ||
address swapMock = 0x60356998558A466Ec51BdE7e78F3b88Bdc843c5e; // Fraxtal MockReceiver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the MockReceiver
contract using a different variable name here. This specific contract was used to test bridging wfrxETH
from a different chain to Fraxtal and atomically swapping and unwrapping to the recipient. You can see the test tx here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used this script to test sending from a different chain to Fraxtal with the composed arguments which are passed into MockReceiver.lzCompose()
.
src/contracts/MockReceiver.sol
Outdated
/// @param _message The encoded message content in the format of the OFTComposeMsgCodec. | ||
/// @param /*Executor*/ Executor address (unused in this mock). | ||
/// @param /*Executor Data*/ Additional data for checking for a specific executor (unused in this mock). | ||
function lzCompose( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is the entry point for receiving a bridge tx from another chain. The process is actually two transactions:
- OFT is minted to this contract (does not callback).
- Endpoint calls
lzCompose()
with the composed message sent with the OFT. At this point, (1) is already executed so the OFT balance should be held within this contract.
src/contracts/MockReceiver.sol
Outdated
address public immutable endpoint; | ||
|
||
address public fraxOft = 0x80Eede496655FB9047dd39d9f418d5483ED600df; | ||
address public fraxCurve = 0x53f8F4e154F68C2D29a0D06BD50f82bCf1bd95dB; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that all curves have the same "a" factor of 1400.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good just some general documentation of the expected flow would be great.
Also some foundry tests would be greatly appreciated.
I am aware that full E2E testing is not possible given the L0 contracts are dependent on their own service.
However, when I was writting tests for the axelar bridge back in the day it is possible to impersonate/vm.load/deal() the destination chain L0 interaction w/n the test case.
This way you can have foundry test cases which cover the happy path in which the off chain service works as expected.
Otherwise looks good would just kill the // TODOs
, document the general interaction flow, and then add some test coverage.
src/contracts/FraxtalStorage.sol
Outdated
|
||
import { FraxtalL2 } from "src/contracts/chain-constants/FraxtalL2.sol"; | ||
|
||
contract FraxtalStorage { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Can we can we rename to FraxtalConstants
Storage implies that the location in which these variables are stored and given they are constants, they are embedded in the bytecode as opposed to storage
src/contracts/FraxtalStorage.sol
Outdated
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import { FraxtalL2 } from "src/contracts/chain-constants/FraxtalL2.sol"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit can we just hardcode the 5 imported variables in this file.
Two reasons for this preference.
- Ease of verification: If the imported file changes it will make verification difficult.
- Info Leak: The whole
FraxtalL2
constants file will be published on the explorer if this is used.
@@ -0,0 +1,14 @@ | |||
//SPDX-License-Identifier: MIT | |||
pragma solidity ^0.8.0; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: Can we add the FRAX ascii
@@ -0,0 +1,95 @@ | |||
// SPDX-License-Identifier: MIT | |||
pragma solidity ^0.8.0; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIt: Ascii
IERC20(token).approve(_oApp, amount); | ||
IOFT(_oApp).send{ value: fee.nativeFee }(sendParam, fee, payable(address(this))); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: consider a rescue function.
Not necessary bc upgradable but nice to have
@@ -0,0 +1,222 @@ | |||
// SPDX-License-Identifier: MIT | |||
pragma solidity ^0.8.0; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Ascii
|
||
import { FraxtalStorage, FraxtalL2 } from "src/contracts/FraxtalStorage.sol"; | ||
|
||
interface ICurve { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Shared Interface Folder, or at end of file
} | ||
|
||
// TODO: AC | ||
function sendToFerry(address _oApp, uint256 _amount) external { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably AC
// TODO: now what | ||
} | ||
|
||
// TODO: AC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍
} | ||
} | ||
constructor() { | ||
_disableInitializers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussion: I think we may be over fitting for upgradability on these contracts.
We have a setter for this variable w/n src/contracts/amos/FraxtalLZCurveAMO.sol
I am curious as to the motivation behind the choice of having proxies and then settable variables referencing said proxies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may be right that some of these contracts don't need to be upgradeable.
Part of the reason behind proxies is because of the Frax Vision 2030: I don't know if contract addresses or wrap-ability will change of tokens so I'd like to keep the contracts flexible in case there's a difference in contract functionality. Ultimately, I want to reduce the need to re-deploy and making the contracts slightly more complicated is worth it IMO. Do you think there would be a security concern from users in using non-immutable contracts here?
The setters within FraxtalLZCurveAMO
are needed because of the operations flow: the Ethereum contracts need the Fraxtal AMO address and the Fraxtal AMO needs the Ethereum addresses. Which means we have to call setters on one side to fully plug together the contracts (unless we went with create2 pre-determined addresses but I don't believe that's necessary here).
Sounds good. I'm realizing that flow charts are needed here now and will get those built out. The TODOs will slowly disappear well. Regarding the tests, there's some fancy calldata that gets sent around by L0 which may be hard to impersonate. I'll do some testing in prod and then replicate the txs in foundry. Does that work? |
No description provided.