Skip to content

Commit

Permalink
Updated readme and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
yahgwai committed Dec 20, 2024
1 parent 9f56d06 commit b7a86ac
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 18 deletions.
8 changes: 4 additions & 4 deletions test/foundry/fee-token-pricers/ConstantExchangeRatePricer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ pragma solidity ^0.8.0;

import {IFeeTokenPricer} from "../../../src/bridge/ISequencerInbox.sol";

/**
* @title Test implementation of a fee token pricer that returns a constant exchange rate
* @notice Exchange rate is set in constructor and cannot be changed
*/
// NOTICE: This contract has not been audited or properly tested. It is for example purposes only

/// @title A constant price fee token pricer
/// @notice The most simple kind of fee token pricer, does not account for any change in exchange rate
contract ConstantExchangeRatePricer is IFeeTokenPricer {
uint256 immutable exchangeRate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ pragma solidity ^0.8.0;
import {IFeeTokenPricer} from "../../../src/bridge/ISequencerInbox.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title Test implementation of a fee token pricer that returns an exchange rate set by the owner
* @notice Exchange rate can be changed by the owner at any time, without any restrictions
*/
/// @title A uniswap twap pricer
/// @notice An example of a type 1 fee token pricer. The owner can adjust the exchange rate at any time
/// to ensure the batch poster is reimbursed an appropriate amount on the child chain
contract OwnerAdjustableExchangeRatePricer is IFeeTokenPricer, Ownable {
uint256 public exchangeRate;

Expand Down
20 changes: 13 additions & 7 deletions test/foundry/fee-token-pricers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,28 @@ When the batch poster posts data to the parent chain a batch spending report is

Although the batch poster is receiving reimbursement in units of the child chain fee token rather than the parent chain units which they used to pay for gas, the value that they are reimbursed should be equal to the value that they paid.

## Fee token pricer options
A chain can choose different fee token pricer implementations to retrieve the exchange rate. Since the fees are reimbursed in child chain tokens but paid for in the parent chain tokens, there is an exchange rate risk. If the price deviates a lot before the batch poster converts the child chain currency back to parent chain currency, they may end up receiving less or more tokens than they originally paid for in gas. Below are some implementation options for the fee token pricer that have different tradeoffs for the batch poster and chain owner. Since the chain owner can change the fee token pricer at any time, the batch poster must always trust the chain owner not to do this for malicious purpose.
## Fee token pricer types
A chain can choose different fee token pricer implementations to retrieve the exchange rate. Since the fees are reimbursed in child chain tokens but paid for in the parent chain tokens, there is an exchange rate risk. If the price deviates a lot before the batch poster converts the child chain currency back to parent chain currency, they may end up receiving less or more tokens than they originally paid for in gas. Below are some implementation types for the fee token pricer that have different tradeoffs for the batch poster and chain owner. Since the chain owner can change the fee token pricer at any time, the batch poster must always trust the chain owner not to do this for malicious purpose.

**Note.** There are some examples of these pricers in this repo, however none of these examples have been audited or properly tested, and are not ready for production use. These are example implementations to give an idea of the different options. Chain owners are expected to implement their own fee token pricer.

### Option 1 - Chain owner defined oracle
### Type 1 - Chain owner defined oracle
In this option the chain owner simply updated the exchange rate manually. This is the simplest option as it requires no external oracle or complicated implementation. However, unless the chain owner updates the price regularly it may diverge from the real price, causing under or over reimbursement. Additionally, unless a further safe guards are added, the batch poster must completely trust the chain owner to reimburse the correct amount. This option makes the most sense for a new chain, and where the batch poster and chain owner are the same entity or have a trusted relationship. The batch poster must also have an appetite for exchange risk, however this can be mitigated by artificially inflating the price to reduce the chance the batch poster is under reimbursed.

### Option 2 - External oracle
### Type 2 - External oracle
In this option an external oracle is used to fetch the exchange rate. Here the fee token pricer is responsible for ensuring the price is in the correct format and applying any safe guards that might be relevant. This option is easier to maintain that option 1. since an external party is reponsible for keep an up to date price on chain. However this places trust in the external party to keep the price up to date and to provide the correct price. To that end the pricer may apply some safe guards to avoid the price going too high or too low. This option also carries the same exchange risk as option 1, so a similar mitigation of marking up the price by a small amount might help to avoid under reimbursement

An example of this approach can be seen in [UniswapV2TwapPricer.sol](./uniswap-v2-twap/UniswapV2TwapPricer.sol).

### Option 3 - Exchange rate tracking
### Type 3 - Exchange rate tracking
In this option it is assumed the batch poster has units of the child chain token and needs to trade them for units of the parent chain token to pay for the gas. They can record the exchange rate they used for this original trade in the fee token pricer, which will return that price when the batch poster requests an exchange rate to use. This removes the exchange risk problem, at the expense of a more complex accounting system in the fee token pricer. In this option the batch poster is implicitly a holder of the same number of child chain tokens at all times, they are not guaranteed any number of parent chain tokens.

The trust model in this approach is not that the batch poster is forced to honestly report the correct price, but instead that the batch poster can be sure that they'll be refunded the correct amount.
The trust model in this approach is not that the batch poster is not forced to honestly report the correct price, but instead that the batch poster can be sure that they'll be refunded the correct amount.

An example of this approach can be seen in [TradeTracker.sol](./trade-tracker/TradeTracker.sol).
An example of this approach can be seen in [TradeTracker.sol](./trade-tracker/TradeTracker.sol).

## Fee token pricer implementation considerations
When implementing a fee token pricer the trust assumptions of each of the involved parties must be considered.
* **Chain owner** - the chain owner is always trusted as they can change the fee token pricer at any time
* **Batch poster** - the batch poster is already trusted to provide valid batches that don't inflate data costs for users. In a type 3 fee token pricer they are additionally trusted to report the correct trade price
* **External parties** - in a type 2 fee token pricer an external party is trusted to provide up to date price information. If the price provided is too low the batch poster will be under-refunded, if the price provided is too high the batch poster will be over-refunded. To that end implementers should consider including price guards in their pricer to ensure the external can't provide values too far from the correct price. As an example, if the external party chose to set the price to max(uint) it would drain the child chain's gas pool, and dramatically raise the price for users. The chain owner would need to call admin functions to reset the sytem. This could be avoided by putting logic in the pricer to prevent extreme values.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import {IFeeTokenPricer} from "../../../../src/bridge/ISequencerInbox.sol";
import {FixedPoint} from "./FixedPoint.sol";
import {IUniswapV2Pair} from "@uniswap/v2-core/interfaces/IUniswapV2Pair.sol";

/**
* @title Test implementation of a fee token pricer that uses Uniswap V2 TWAP
*/
/// @title A uniswap twap pricer
/// @notice An example of a type 2 fee token pricer. It uses an oracle to get the fee token price at
/// at the time the batch is posted
contract UniswapV2TwapPricer is IFeeTokenPricer {
using FixedPoint for *;

Expand Down

0 comments on commit b7a86ac

Please sign in to comment.