Skip to content

Commit

Permalink
Merge pull request #440 from FastLane-Labs/set-surcharge-rates
Browse files Browse the repository at this point in the history
refactor: set surcharge rates in constructor
  • Loading branch information
BenSparksCode authored Oct 11, 2024
2 parents 7ed34b9 + 1dd15ac commit 52cfec4
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 192 deletions.
8 changes: 7 additions & 1 deletion script/deploy-atlas.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import { Sorter } from "src/contracts/helpers/Sorter.sol";
import { ExecutionEnvironment } from "src/contracts/common/ExecutionEnvironment.sol";

contract DeployAtlasScript is DeployBaseScript {
uint256 ESCROW_DURATION = 64;
uint256 ATLAS_SURCHARGE_RATE = 1_000_000; // 10%
uint256 BUNDLER_SURCHARGE_RATE = 1_000_000; // 10%

function run() external {
console.log("\n=== DEPLOYING Atlas ===\n");

Expand All @@ -37,7 +41,9 @@ contract DeployAtlasScript is DeployBaseScript {

ExecutionEnvironment execEnvTemplate = new ExecutionEnvironment(expectedAtlasAddr);
atlas = new Atlas({
escrowDuration: 64,
escrowDuration: ESCROW_DURATION,
atlasSurchargeRate: ATLAS_SURCHARGE_RATE,
bundlerSurchargeRate: BUNDLER_SURCHARGE_RATE,
verification: expectedAtlasVerificationAddr,
simulator: expectedSimulatorAddr,
executionTemplate: address(execEnvTemplate),
Expand Down
12 changes: 11 additions & 1 deletion src/contracts/atlas/AtlETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ import "src/contracts/types/EscrowTypes.sol";
abstract contract AtlETH is Permit69 {
constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator
)
Permit69(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
Permit69(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
{ }

/*//////////////////////////////////////////////////////////////
Expand Down
12 changes: 11 additions & 1 deletion src/contracts/atlas/Atlas.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@ contract Atlas is Escrow, Factory {

constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator,
address executionTemplate
)
Escrow(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
Escrow(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
Factory(executionTemplate)
{ }

Expand Down
12 changes: 11 additions & 1 deletion src/contracts/atlas/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,22 @@ abstract contract Escrow is AtlETH {

constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator
)
AtlETH(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
AtlETH(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
{
if (escrowDuration == 0) revert InvalidEscrowDuration();
}
Expand Down
28 changes: 19 additions & 9 deletions src/contracts/atlas/GasAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@ abstract contract GasAccounting is SafetyLocks {

constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator
)
SafetyLocks(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
SafetyLocks(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
{ }

/// @notice Sets the initial accounting values for the metacall transaction.
Expand All @@ -35,10 +45,10 @@ abstract contract GasAccounting is SafetyLocks {
uint256 _rawClaims = (FIXED_GAS_OFFSET + gasMarker) * tx.gasprice;

// Set any withdraws or deposits
_setClaims(_rawClaims.withBundlerSurcharge());
_setClaims(_rawClaims.withSurcharge(BUNDLER_SURCHARGE_RATE));

// Atlas surcharge is based on the raw claims value.
_setFees(_rawClaims.getAtlasSurcharge());
_setFees(_rawClaims.getSurcharge(ATLAS_SURCHARGE_RATE));
_setDeposits(msg.value);

// Explicitly set writeoffs and withdrawals to 0 in case multiple metacalls in single tx.
Expand Down Expand Up @@ -281,16 +291,16 @@ abstract contract GasAccounting is SafetyLocks {
if (result.bundlersFault()) {
// CASE: Solver is not responsible for the failure of their operation, so we blame the bundler
// and reduce the total amount refunded to the bundler
_setWriteoffs(writeoffs() + _gasUsed.withAtlasAndBundlerSurcharges());
_setWriteoffs(writeoffs() + _gasUsed.withSurcharges(ATLAS_SURCHARGE_RATE, BUNDLER_SURCHARGE_RATE));
} else {
// CASE: Solver failed, so we calculate what they owe.
uint256 _gasUsedWithSurcharges = _gasUsed.withAtlasAndBundlerSurcharges();
uint256 _gasUsedWithSurcharges = _gasUsed.withSurcharges(ATLAS_SURCHARGE_RATE, BUNDLER_SURCHARGE_RATE);
_assign(solverOp.from, _gasUsedWithSurcharges, _gasUsedWithSurcharges, false);
}
}

function _writeOffBidFindGasCost(uint256 gasUsed) internal {
_setWriteoffs(writeoffs() + gasUsed.withAtlasAndBundlerSurcharges());
_setWriteoffs(writeoffs() + gasUsed.withSurcharges(ATLAS_SURCHARGE_RATE, BUNDLER_SURCHARGE_RATE));
}

/// @param ctx Context struct containing relevant context information for the Atlas auction.
Expand Down Expand Up @@ -332,17 +342,17 @@ abstract contract GasAccounting is SafetyLocks {
uint256 _gasRemainder = _gasLeft * tx.gasprice;

// Calculate the preadjusted netAtlasGasSurcharge
netAtlasGasSurcharge = _fees - _gasRemainder.getAtlasSurcharge();
netAtlasGasSurcharge = _fees - _gasRemainder.getSurcharge(ATLAS_SURCHARGE_RATE);

adjustedClaims -= _gasRemainder.withBundlerSurcharge();
adjustedClaims -= _gasRemainder.withSurcharge(BUNDLER_SURCHARGE_RATE);
adjustedWithdrawals += netAtlasGasSurcharge;
S_cumulativeSurcharge = _surcharge + netAtlasGasSurcharge; // Update the cumulative surcharge

// Calculate whether or not the bundler used an excessive amount of gas and, if so, reduce their
// gas rebate. By reducing the claims, solvers end up paying less in total.
if (ctx.solverCount > 0) {
// Calculate the unadjusted bundler gas surcharge
uint256 _grossBundlerGasSurcharge = adjustedClaims.withoutBundlerSurcharge();
uint256 _grossBundlerGasSurcharge = adjustedClaims.withoutSurcharge(BUNDLER_SURCHARGE_RATE);

// Calculate an estimate for how much gas should be remaining
// NOTE: There is a free buffer of one SolverOperation because solverIndex starts at 0.
Expand Down
12 changes: 11 additions & 1 deletion src/contracts/atlas/Permit69.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,22 @@ import "src/contracts/types/EscrowTypes.sol";
abstract contract Permit69 is GasAccounting {
constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator
)
GasAccounting(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
GasAccounting(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
{ }

/// @notice Verifies that the caller is an authorized Execution Environment contract.
Expand Down
12 changes: 11 additions & 1 deletion src/contracts/atlas/SafetyLocks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,22 @@ abstract contract SafetyLocks is Storage {

constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
address l2GasCalculator
)
Storage(escrowDuration, verification, simulator, initialSurchargeRecipient, l2GasCalculator)
Storage(
escrowDuration,
atlasSurchargeRate,
bundlerSurchargeRate,
verification,
simulator,
initialSurchargeRecipient,
l2GasCalculator
)
{ }

/// @notice Sets the Atlas lock to the specified execution environment.
Expand Down
8 changes: 6 additions & 2 deletions src/contracts/atlas/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {
address public immutable SIMULATOR;
address public immutable L2_GAS_CALCULATOR;
uint256 public immutable ESCROW_DURATION;
uint256 public immutable ATLAS_SURCHARGE_RATE;
uint256 public immutable BUNDLER_SURCHARGE_RATE;

// AtlETH public constants
// These constants double as interface functions for the ERC20 standard, hence the lowercase naming convention.
Expand All @@ -26,8 +28,6 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {
uint8 public constant decimals = 18;

// Gas Accounting public constants
uint256 public constant ATLAS_SURCHARGE_RATE = AccountingMath._ATLAS_SURCHARGE_RATE;
uint256 public constant BUNDLER_SURCHARGE_RATE = AccountingMath._BUNDLER_SURCHARGE_RATE;
uint256 public constant SCALE = AccountingMath._SCALE;
uint256 public constant FIXED_GAS_OFFSET = AccountingMath._FIXED_GAS_OFFSET;

Expand Down Expand Up @@ -56,6 +56,8 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {

constructor(
uint256 escrowDuration,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate,
address verification,
address simulator,
address initialSurchargeRecipient,
Expand All @@ -67,6 +69,8 @@ contract Storage is AtlasEvents, AtlasErrors, AtlasConstants {
SIMULATOR = simulator;
L2_GAS_CALCULATOR = l2GasCalculator;
ESCROW_DURATION = escrowDuration;
ATLAS_SURCHARGE_RATE = atlasSurchargeRate;
BUNDLER_SURCHARGE_RATE = bundlerSurchargeRate;

// Gas Accounting
// Initialized with msg.value to seed flash loan liquidity
Expand Down
33 changes: 23 additions & 10 deletions src/contracts/libraries/AccountingMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,40 @@ pragma solidity 0.8.25;

library AccountingMath {
// Gas Accounting public constants
uint256 internal constant _ATLAS_SURCHARGE_RATE = 1_000_000; // out of 10_000_000 = 10%
uint256 internal constant _BUNDLER_SURCHARGE_RATE = 1_000_000; // out of 10_000_000 = 10%
uint256 internal constant _SOLVER_GAS_LIMIT_BUFFER_PERCENTAGE = 500_000; // out of 10_000_000 = 5%
uint256 internal constant _SCALE = 10_000_000; // 10_000_000 / 10_000_000 = 100%
uint256 internal constant _FIXED_GAS_OFFSET = 85_000;

function withBundlerSurcharge(uint256 amount) internal pure returns (uint256 adjustedAmount) {
adjustedAmount = amount * (_SCALE + _BUNDLER_SURCHARGE_RATE) / _SCALE;
function withSurcharge(uint256 amount, uint256 surchargeRate) internal pure returns (uint256 adjustedAmount) {
adjustedAmount = amount * (_SCALE + surchargeRate) / _SCALE;
}

function withoutBundlerSurcharge(uint256 amount) internal pure returns (uint256 unadjustedAmount) {
unadjustedAmount = amount * _SCALE / (_SCALE + _BUNDLER_SURCHARGE_RATE);
function withoutSurcharge(uint256 amount, uint256 surchargeRate) internal pure returns (uint256 unadjustedAmount) {
unadjustedAmount = amount * _SCALE / (_SCALE + surchargeRate);
}

function withAtlasAndBundlerSurcharges(uint256 amount) internal pure returns (uint256 adjustedAmount) {
adjustedAmount = amount * (_SCALE + _ATLAS_SURCHARGE_RATE + _BUNDLER_SURCHARGE_RATE) / _SCALE;
function withSurcharges(
uint256 amount,
uint256 atlasSurchargeRate,
uint256 bundlerSurchargeRate
)
internal
pure
returns (uint256 adjustedAmount)
{
adjustedAmount = amount * (_SCALE + atlasSurchargeRate + bundlerSurchargeRate) / _SCALE;
}

// gets the Atlas surcharge from an unadjusted amount
function getAtlasSurcharge(uint256 amount) internal pure returns (uint256 surcharge) {
surcharge = amount * _ATLAS_SURCHARGE_RATE / _SCALE;
function getSurcharge(
uint256 unadjustedAmount,
uint256 surchargeRate
)
internal
pure
returns (uint256 surchargeAmount)
{
surchargeAmount = unadjustedAmount * surchargeRate / _SCALE;
}

function solverGasLimitScaledDown(
Expand Down
Loading

0 comments on commit 52cfec4

Please sign in to comment.