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

V0.1.0 #5

Merged
merged 18 commits into from
Nov 13, 2024
Merged

V0.1.0 #5

merged 18 commits into from
Nov 13, 2024

Conversation

pegahcarter
Copy link
Collaborator

No description provided.

* 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
Copy link
Collaborator Author

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.

Copy link
Collaborator Author

@pegahcarter pegahcarter Oct 30, 2024

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().

/// @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(
Copy link
Collaborator Author

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:

  1. OFT is minted to this contract (does not callback).
  2. 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.

address public immutable endpoint;

address public fraxOft = 0x80Eede496655FB9047dd39d9f418d5483ED600df;
address public fraxCurve = 0x53f8F4e154F68C2D29a0D06BD50f82bCf1bd95dB;
Copy link
Collaborator Author

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.

Copy link

@tom2o17 tom2o17 left a 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.


import { FraxtalL2 } from "src/contracts/chain-constants/FraxtalL2.sol";

contract FraxtalStorage {
Copy link

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

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { FraxtalL2 } from "src/contracts/chain-constants/FraxtalL2.sol";
Copy link

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.

  1. Ease of verification: If the imported file changes it will make verification difficult.
  2. 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;

Copy link

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;

Copy link

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)));
}

Copy link

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;

Copy link

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 {
Copy link

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 {
Copy link

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍

}
}
constructor() {
_disableInitializers();
Copy link

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.

Copy link
Collaborator Author

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).

@pegahcarter
Copy link
Collaborator Author

@tom2o17

Otherwise looks good would just kill the // TODOs, document the general interaction flow, and then add some test coverage.

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?

@pegahcarter pegahcarter merged commit bc36f7e into master Nov 13, 2024
1 check passed
@pegahcarter pegahcarter deleted the v0.1.0 branch February 26, 2025 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants