Contract Name:
FluidDexFactory
Contract Source Code:
<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
/// @notice implements calculation of address for contracts deployed through CREATE.
/// Accepts contract deployed from which address & nonce
library AddressCalcs {
/// @notice Computes the address of a contract based
/// @param deployedFrom_ Address from which the contract was deployed
/// @param nonce_ Nonce at which the contract was deployed
/// @return contract_ Address of deployed contract
function addressCalc(address deployedFrom_, uint nonce_) internal pure returns (address contract_) {
// @dev based on https://ethereum.stackexchange.com/a/61413
// nonce of smart contract always starts with 1. so, with nonce 0 there won't be any deployment
// hence, nonce of vault deployment starts with 1.
bytes memory data;
if (nonce_ == 0x00) {
return address(0);
} else if (nonce_ <= 0x7f) {
data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployedFrom_, uint8(nonce_));
} else if (nonce_ <= 0xff) {
data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployedFrom_, bytes1(0x81), uint8(nonce_));
} else if (nonce_ <= 0xffff) {
data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployedFrom_, bytes1(0x82), uint16(nonce_));
} else if (nonce_ <= 0xffffff) {
data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployedFrom_, bytes1(0x83), uint24(nonce_));
} else {
data = abi.encodePacked(bytes1(0xda), bytes1(0x94), deployedFrom_, bytes1(0x84), uint32(nonce_));
}
return address(uint160(uint256(keccak256(data))));
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
/// @notice implements a method to read uint256 data from storage at a bytes32 storage slot key.
contract StorageRead {
function readFromStorage(bytes32 slot_) public view returns (uint256 result_) {
assembly {
result_ := sload(slot_) // read value from the storage slot
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
import { Structs } from "./poolT1/coreModule/structs.sol";
abstract contract Error {
error FluidDexError(uint256 errorId_);
error FluidDexFactoryError(uint256 errorId);
/// @notice used to simulate swap to find the output amount
error FluidDexSwapResult(uint256 amountOut);
error FluidDexPerfectLiquidityOutput(uint256 token0Amt, uint token1Amt);
error FluidDexSingleTokenOutput(uint256 tokenAmt);
error FluidDexLiquidityOutput(uint256 shares_);
error FluidDexPricesAndExchangeRates(Structs.PricesAndExchangePrice pex_);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
library ErrorTypes {
/***********************************|
| DexT1 |
|__________________________________*/
/// @notice thrown at reentrancy
uint256 internal constant DexT1__AlreadyEntered = 51001;
uint256 internal constant DexT1__NotAnAuth = 51002;
uint256 internal constant DexT1__SmartColNotEnabled = 51003;
uint256 internal constant DexT1__SmartDebtNotEnabled = 51004;
uint256 internal constant DexT1__PoolNotInitialized = 51005;
uint256 internal constant DexT1__TokenReservesTooLow = 51006;
uint256 internal constant DexT1__EthAndAmountInMisMatch = 51007;
uint256 internal constant DexT1__EthSentForNonNativeSwap = 51008;
uint256 internal constant DexT1__NoSwapRoute = 51009;
uint256 internal constant DexT1__NotEnoughAmountOut = 51010;
uint256 internal constant DexT1__LiquidityLayerTokenUtilizationCapReached = 51011;
uint256 internal constant DexT1__HookReturnedFalse = 51012;
// Either user's config are not set or user is paused
uint256 internal constant DexT1__UserSupplyInNotOn = 51013;
// Either user's config are not set or user is paused
uint256 internal constant DexT1__UserDebtInNotOn = 51014;
// Thrown when contract asks for more token0 or token1 than what user's wants to give on deposit
uint256 internal constant DexT1__AboveDepositMax = 51015;
uint256 internal constant DexT1__MsgValueLowOnDepositOrPayback = 51016;
uint256 internal constant DexT1__WithdrawLimitReached = 51017;
// Thrown when contract gives less token0 or token1 than what user's wants on withdraw
uint256 internal constant DexT1__BelowWithdrawMin = 51018;
uint256 internal constant DexT1__DebtLimitReached = 51019;
// Thrown when contract gives less token0 or token1 than what user's wants on borrow
uint256 internal constant DexT1__BelowBorrowMin = 51020;
// Thrown when contract asks for more token0 or token1 than what user's wants on payback
uint256 internal constant DexT1__AbovePaybackMax = 51021;
uint256 internal constant DexT1__InvalidDepositAmts = 51022;
uint256 internal constant DexT1__DepositAmtsZero = 51023;
uint256 internal constant DexT1__SharesMintedLess = 51024;
uint256 internal constant DexT1__WithdrawalNotEnough = 51025;
uint256 internal constant DexT1__InvalidWithdrawAmts = 51026;
uint256 internal constant DexT1__WithdrawAmtsZero = 51027;
uint256 internal constant DexT1__WithdrawExcessSharesBurn = 51028;
uint256 internal constant DexT1__InvalidBorrowAmts = 51029;
uint256 internal constant DexT1__BorrowAmtsZero = 51030;
uint256 internal constant DexT1__BorrowExcessSharesMinted = 51031;
uint256 internal constant DexT1__PaybackAmtTooHigh = 51032;
uint256 internal constant DexT1__InvalidPaybackAmts = 51033;
uint256 internal constant DexT1__PaybackAmtsZero = 51034;
uint256 internal constant DexT1__PaybackSharedBurnedLess = 51035;
uint256 internal constant DexT1__NothingToArbitrage = 51036;
uint256 internal constant DexT1__MsgSenderNotLiquidity = 51037;
// On liquidity callback reentrancy bit should be on
uint256 internal constant DexT1__ReentrancyBitShouldBeOn = 51038;
// Thrown is reentrancy is already on and someone tries to fetch oracle price. Should not be possible to this
uint256 internal constant DexT1__OraclePriceFetchAlreadyEntered = 51039;
// Thrown when swap changes the current price by more than 5%
uint256 internal constant DexT1__OracleUpdateHugeSwapDiff = 51040;
uint256 internal constant DexT1__Token0ShouldBeSmallerThanToken1 = 51041;
uint256 internal constant DexT1__OracleMappingOverflow = 51042;
/// @notice thrown if governance has paused the swapping & arbitrage so only perfect functions are usable
uint256 internal constant DexT1__SwapAndArbitragePaused = 51043;
uint256 internal constant DexT1__ExceedsAmountInMax = 51044;
/// @notice thrown if amount in is too high or too low
uint256 internal constant DexT1__SwapInLimitingAmounts = 51045;
/// @notice thrown if amount out is too high or too low
uint256 internal constant DexT1__SwapOutLimitingAmounts = 51046;
uint256 internal constant DexT1__MintAmtOverflow = 51047;
uint256 internal constant DexT1__BurnAmtOverflow = 51048;
uint256 internal constant DexT1__LimitingAmountsSwapAndNonPerfectActions = 51049;
uint256 internal constant DexT1__InsufficientOracleData = 51050;
uint256 internal constant DexT1__SharesAmountInsufficient = 51051;
uint256 internal constant DexT1__CenterPriceOutOfRange = 51052;
uint256 internal constant DexT1__DebtReservesTooLow = 51053;
uint256 internal constant DexT1__SwapAndDepositTooLowOrTooHigh = 51054;
uint256 internal constant DexT1__WithdrawAndSwapTooLowOrTooHigh = 51055;
uint256 internal constant DexT1__BorrowAndSwapTooLowOrTooHigh = 51056;
uint256 internal constant DexT1__SwapAndPaybackTooLowOrTooHigh = 51057;
uint256 internal constant DexT1__InvalidImplementation = 51058;
uint256 internal constant DexT1__OnlyDelegateCallAllowed = 51059;
uint256 internal constant DexT1__IncorrectDataLength = 51060;
uint256 internal constant DexT1__AmountToSendLessThanAmount = 51061;
uint256 internal constant DexT1__InvalidCollateralReserves = 51062;
uint256 internal constant DexT1__InvalidDebtReserves = 51063;
uint256 internal constant DexT1__SupplySharesOverflow = 51064;
uint256 internal constant DexT1__BorrowSharesOverflow = 51065;
uint256 internal constant DexT1__OracleNotActive = 51066;
/***********************************|
| DEX Admin |
|__________________________________*/
/// @notice thrown when pool is not initialized
uint256 internal constant DexT1Admin__PoolNotInitialized = 52001;
uint256 internal constant DexT1Admin__SmartColIsAlreadyOn = 52002;
uint256 internal constant DexT1Admin__SmartDebtIsAlreadyOn = 52003;
/// @notice thrown when any of the configs value overflow the maximum limit
uint256 internal constant DexT1Admin__ConfigOverflow = 52004;
uint256 internal constant DexT1Admin__AddressNotAContract = 52005;
uint256 internal constant DexT1Admin__InvalidParams = 52006;
uint256 internal constant DexT1Admin__UserNotDefined = 52007;
uint256 internal constant DexT1Admin__OnlyDelegateCallAllowed = 52008;
uint256 internal constant DexT1Admin__UnexpectedPoolState = 52009;
/// @notice thrown when trying to pause or unpause but user is already in the target pause state
uint256 internal constant DexT1Admin__InvalidPauseToggle = 52009;
/***********************************|
| DEX Factory |
|__________________________________*/
uint256 internal constant DexFactory__InvalidOperation = 53001;
uint256 internal constant DexFactory__Unauthorized = 53002;
uint256 internal constant DexFactory__SameTokenNotAllowed = 53003;
uint256 internal constant DexFactory__TokenConfigNotProper = 53004;
uint256 internal constant DexFactory__InvalidParams = 53005;
uint256 internal constant DexFactory__OnlyDelegateCallAllowed = 53006;
uint256 internal constant DexFactory__InvalidDexAddress = 53007;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
import { Owned } from "solmate/src/auth/Owned.sol";
import { ErrorTypes } from "../errorTypes.sol";
import { Error } from "../error.sol";
import { AddressCalcs } from "../../../libraries/addressCalcs.sol";
import { StorageRead } from "../../../libraries/storageRead.sol";
abstract contract DexFactoryVariables is Owned, StorageRead, Error {
/*//////////////////////////////////////////////////////////////
STORAGE VARIABLES
//////////////////////////////////////////////////////////////*/
// ------------ storage variables from inherited contracts (Owned) come before vars here --------
// ----------------------- slot 0 ---------------------------
// address public owner; // from Owned
// 12 bytes empty
// ----------------------- slot 1 ---------------------------
/// @dev deployer can deploy new Dex Pool contract
/// owner can add/remove deployer.
/// Owner is deployer by default.
mapping(address => bool) internal _deployers;
// ----------------------- slot 2 ---------------------------
/// @dev global auths can update any dex pool config.
/// owner can add/remove global auths.
/// Owner is global auth by default.
mapping(address => bool) internal _globalAuths;
// ----------------------- slot 3 ---------------------------
/// @dev dex auths can update specific dex config.
/// owner can add/remove dex auths.
/// Owner is dex auth by default.
/// dex => auth => add/remove
mapping(address => mapping(address => bool)) internal _dexAuths;
// ----------------------- slot 4 ---------------------------
/// @dev total no of dexes deployed by the factory
/// only addresses that have deployer role or owner can deploy new dex pool.
uint256 internal _totalDexes;
// ----------------------- slot 5 ---------------------------
/// @dev dex deployment logics for deploying dex pool
/// These logic contracts hold the deployment logics of specific dexes and are called via .delegatecall inside deployDex().
/// only addresses that have owner can add/remove new dex deployment logic.
mapping(address => bool) internal _dexDeploymentLogics;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address owner_) Owned(owner_) {}
}
abstract contract DexFactoryEvents {
/// @dev Emitted when a new dex is deployed.
/// @param dex The address of the newly deployed dex.
/// @param dexId The id of the newly deployed dex.
event LogDexDeployed(address indexed dex, uint256 indexed dexId);
/// @dev Emitted when the deployer is modified by owner.
/// @param deployer Address whose deployer status is updated.
/// @param allowed Indicates whether the address is authorized as a deployer or not.
event LogSetDeployer(address indexed deployer, bool indexed allowed);
/// @dev Emitted when the globalAuth is modified by owner.
/// @param globalAuth Address whose globalAuth status is updated.
/// @param allowed Indicates whether the address is authorized as a deployer or not.
event LogSetGlobalAuth(address indexed globalAuth, bool indexed allowed);
/// @dev Emitted when the dexAuth is modified by owner.
/// @param dexAuth Address whose dexAuth status is updated.
/// @param allowed Indicates whether the address is authorized as a deployer or not.
/// @param dex Address of the specific dex related to the authorization change.
event LogSetDexAuth(address indexed dexAuth, bool indexed allowed, address indexed dex);
/// @dev Emitted when the dex deployment logic is modified by owner.
/// @param dexDeploymentLogic The address of the dex deployment logic contract.
/// @param allowed Indicates whether the address is authorized as a deployer or not.
event LogSetDexDeploymentLogic(address indexed dexDeploymentLogic, bool indexed allowed);
}
abstract contract DexFactoryCore is DexFactoryVariables, DexFactoryEvents {
constructor(address owner_) validAddress(owner_) DexFactoryVariables(owner_) {}
/// @dev validates that an address is not the zero address
modifier validAddress(address value_) {
if (value_ == address(0)) {
revert FluidDexFactoryError(ErrorTypes.DexFactory__InvalidParams);
}
_;
}
}
/// @dev Implements Dex Factory auth-only callable methods. Owner / auths can set various config values and
/// can define the allow-listed deployers.
abstract contract DexFactoryAuth is DexFactoryCore {
/// @notice Sets an address (`deployer_`) as allowed deployer or not.
/// This function can only be called by the owner.
/// @param deployer_ The address to be set as deployer.
/// @param allowed_ A boolean indicating whether the specified address is allowed to deploy dexes.
function setDeployer(address deployer_, bool allowed_) external onlyOwner validAddress(deployer_) {
_deployers[deployer_] = allowed_;
emit LogSetDeployer(deployer_, allowed_);
}
/// @notice Sets an address (`globalAuth_`) as a global authorization or not.
/// This function can only be called by the owner.
/// @param globalAuth_ The address to be set as global authorization.
/// @param allowed_ A boolean indicating whether the specified address is allowed to update any dex config.
function setGlobalAuth(address globalAuth_, bool allowed_) external onlyOwner validAddress(globalAuth_) {
_globalAuths[globalAuth_] = allowed_;
emit LogSetGlobalAuth(globalAuth_, allowed_);
}
/// @notice Sets an address (`dexAuth_`) as allowed dex authorization or not for a specific dex (`dex_`).
/// This function can only be called by the owner.
/// @param dex_ The address of the dex for which the authorization is being set.
/// @param dexAuth_ The address to be set as dex authorization.
/// @param allowed_ A boolean indicating whether the specified address is allowed to update the specific dex config.
function setDexAuth(address dex_, address dexAuth_, bool allowed_) external onlyOwner validAddress(dexAuth_) {
_dexAuths[dex_][dexAuth_] = allowed_;
emit LogSetDexAuth(dexAuth_, allowed_, dex_);
}
/// @notice Sets an address as allowed dex deployment logic (`deploymentLogic_`) contract or not.
/// This function can only be called by the owner.
/// @param deploymentLogic_ The address of the dex deployment logic contract to be set.
/// @param allowed_ A boolean indicating whether the specified address is allowed to deploy new type of dex.
function setDexDeploymentLogic(
address deploymentLogic_,
bool allowed_
) public onlyOwner validAddress(deploymentLogic_) {
_dexDeploymentLogics[deploymentLogic_] = allowed_;
emit LogSetDexDeploymentLogic(deploymentLogic_, allowed_);
}
/// @notice Spell allows owner aka governance to do any arbitrary call on factory
/// @param target_ Address to which the call needs to be delegated
/// @param data_ Data to execute at the delegated address
function spell(address target_, bytes memory data_) external onlyOwner returns (bytes memory response_) {
assembly {
let succeeded := delegatecall(gas(), target_, add(data_, 0x20), mload(data_), 0, 0)
let size := returndatasize()
response_ := mload(0x40)
mstore(0x40, add(response_, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response_, size)
returndatacopy(add(response_, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
returndatacopy(0x00, 0x00, size)
revert(0x00, size)
}
}
}
/// @notice Checks if the provided address (`deployer_`) is authorized as a deployer.
/// @param deployer_ The address to be checked for deployer authorization.
/// @return Returns `true` if the address is a deployer, otherwise `false`.
function isDeployer(address deployer_) public view returns (bool) {
return _deployers[deployer_] || owner == deployer_;
}
/// @notice Checks if the provided address (`globalAuth_`) has global dex authorization privileges.
/// @param globalAuth_ The address to be checked for global authorization privileges.
/// @return Returns `true` if the given address has global authorization privileges, otherwise `false`.
function isGlobalAuth(address globalAuth_) public view returns (bool) {
return _globalAuths[globalAuth_] || owner == globalAuth_;
}
/// @notice Checks if the provided address (`dexAuth_`) has dex authorization privileges for the specified dex (`dex_`).
/// @param dex_ The address of the dex to check.
/// @param dexAuth_ The address to be checked for dex authorization privileges.
/// @return Returns `true` if the given address has dex authorization privileges for the specified dex, otherwise `false`.
function isDexAuth(address dex_, address dexAuth_) public view returns (bool) {
return _dexAuths[dex_][dexAuth_] || owner == dexAuth_;
}
/// @notice Checks if the provided (`dexDeploymentLogic_`) address has authorization for dex deployment.
/// @param dexDeploymentLogic_ The address of the dex deploy logic to check for authorization privileges.
/// @return Returns `true` if the given address has authorization privileges for dex deployment, otherwise `false`.
function isDexDeploymentLogic(address dexDeploymentLogic_) public view returns (bool) {
return _dexDeploymentLogics[dexDeploymentLogic_];
}
}
/// @dev implements DexFactory deploy dex related methods.
abstract contract DexFactoryDeployment is DexFactoryCore, DexFactoryAuth {
/// @dev Deploys a contract using the CREATE opcode with the provided bytecode (`bytecode_`).
/// This is an internal function, meant to be used within the contract to facilitate the deployment of other contracts.
/// @param bytecode_ The bytecode of the contract to be deployed.
/// @return address_ Returns the address of the deployed contract.
function _deploy(bytes memory bytecode_) internal returns (address address_) {
if (bytecode_.length == 0) {
revert FluidDexError(ErrorTypes.DexFactory__InvalidOperation);
}
/// @solidity memory-safe-assembly
assembly {
address_ := create(0, add(bytecode_, 0x20), mload(bytecode_))
}
if (address_ == address(0)) {
revert FluidDexError(ErrorTypes.DexFactory__InvalidOperation);
}
}
/// @notice Deploys a new dex using the specified deployment logic `dexDeploymentLogic_` and data `dexDeploymentData_`.
/// Only accounts with deployer access or the owner can deploy a new dex.
/// @param dexDeploymentLogic_ The address of the dex deployment logic contract.
/// @param dexDeploymentData_ The data to be used for dex deployment.
/// @return dex_ Returns the address of the newly deployed dex.
function deployDex(address dexDeploymentLogic_, bytes calldata dexDeploymentData_) external returns (address dex_) {
// Revert if msg.sender doesn't have deployer access or is an owner.
if (!isDeployer(msg.sender)) revert FluidDexError(ErrorTypes.DexFactory__Unauthorized);
// Revert if dexDeploymentLogic_ is not whitelisted.
if (!isDexDeploymentLogic(dexDeploymentLogic_)) revert FluidDexError(ErrorTypes.DexFactory__Unauthorized);
// Dex ID for the new dex and also acts as `nonce` for CREATE
uint256 dexId_ = ++_totalDexes;
// compute dex address for dex id.
dex_ = getDexAddress(dexId_);
// deploy the dex using dex deployment logic by making .delegatecall
(bool success_, bytes memory data_) = dexDeploymentLogic_.delegatecall(dexDeploymentData_);
if (!(success_ && dex_ == _deploy(abi.decode(data_, (bytes))) && isDex(dex_))) {
revert FluidDexError(ErrorTypes.DexFactory__InvalidDexAddress);
}
emit LogDexDeployed(dex_, dexId_);
}
/// @notice Computes the address of a dex based on its given ID (`dexId_`).
/// @param dexId_ The ID of the dex.
/// @return dex_ Returns the computed address of the dex.
function getDexAddress(uint256 dexId_) public view returns (address dex_) {
return AddressCalcs.addressCalc(address(this), dexId_);
}
/// @notice Checks if a given address (`dex_`) corresponds to a valid dex.
/// @param dex_ The dex address to check.
/// @return Returns `true` if the given address corresponds to a valid dex, otherwise `false`.
function isDex(address dex_) public view returns (bool) {
if (dex_.code.length == 0) {
return false;
} else {
// DEX_ID() function signature is 0xf4b9a3fb
(bool success_, bytes memory data_) = dex_.staticcall(hex"f4b9a3fb");
return success_ && dex_ == getDexAddress(abi.decode(data_, (uint256)));
}
}
/// @notice Returns the total number of dexes deployed by the factory.
/// @return Returns the total number of dexes.
function totalDexes() external view returns (uint256) {
return _totalDexes;
}
}
/// @title Fluid DexFactory
/// @notice creates Fluid dex protocol dexes, which are interacting with Fluid Liquidity to deposit / borrow funds.
/// Dexes are created at a deterministic address, given an incrementing `dexId` (see `getDexAddress()`).
/// Dexes can only be deployed by allow-listed deployer addresses.
/// @dev Note the deployed dexes start out with no config at Liquidity contract.
/// This must be done by Liquidity auths in a separate step, otherwise no deposits will be possible.
/// This contract is not upgradeable. It supports adding new dex deployment logic contracts for new, future dexes.
contract FluidDexFactory is DexFactoryCore, DexFactoryAuth, DexFactoryDeployment {
constructor(address owner_) DexFactoryCore(owner_) {}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;
abstract contract Structs {
struct PricesAndExchangePrice {
uint lastStoredPrice; // last stored price in 1e27 decimals
uint centerPrice; // last stored price in 1e27 decimals
uint upperRange; // price at upper range in 1e27 decimals
uint lowerRange; // price at lower range in 1e27 decimals
uint geometricMean; // geometric mean of upper range & lower range in 1e27 decimals
uint supplyToken0ExchangePrice;
uint borrowToken0ExchangePrice;
uint supplyToken1ExchangePrice;
uint borrowToken1ExchangePrice;
}
struct ExchangePrices {
uint supplyToken0ExchangePrice;
uint borrowToken0ExchangePrice;
uint supplyToken1ExchangePrice;
uint borrowToken1ExchangePrice;
}
struct CollateralReserves {
uint token0RealReserves;
uint token1RealReserves;
uint token0ImaginaryReserves;
uint token1ImaginaryReserves;
}
struct CollateralReservesSwap {
uint tokenInRealReserves;
uint tokenOutRealReserves;
uint tokenInImaginaryReserves;
uint tokenOutImaginaryReserves;
}
struct DebtReserves {
uint token0Debt;
uint token1Debt;
uint token0RealReserves;
uint token1RealReserves;
uint token0ImaginaryReserves;
uint token1ImaginaryReserves;
}
struct DebtReservesSwap {
uint tokenInDebt;
uint tokenOutDebt;
uint tokenInRealReserves;
uint tokenOutRealReserves;
uint tokenInImaginaryReserves;
uint tokenOutImaginaryReserves;
}
struct SwapInMemory {
address tokenIn;
address tokenOut;
uint256 amtInAdjusted;
address withdrawTo;
address borrowTo;
uint price; // price of pool after swap
uint fee; // fee of pool
uint revenueCut; // revenue cut of pool
bool swap0to1;
int swapRoutingAmt;
bytes data; // just added to avoid stack-too-deep error
}
struct SwapOutMemory {
address tokenIn;
address tokenOut;
uint256 amtOutAdjusted;
address withdrawTo;
address borrowTo;
uint price; // price of pool after swap
uint fee;
uint revenueCut; // revenue cut of pool
bool swap0to1;
int swapRoutingAmt;
bytes data; // just added to avoid stack-too-deep error
uint msgValue;
}
struct DepositColMemory {
uint256 token0AmtAdjusted;
uint256 token1AmtAdjusted;
uint256 token0ReservesInitial;
uint256 token1ReservesInitial;
}
struct WithdrawColMemory {
uint256 token0AmtAdjusted;
uint256 token1AmtAdjusted;
uint256 token0ReservesInitial;
uint256 token1ReservesInitial;
address to;
}
struct BorrowDebtMemory {
uint256 token0AmtAdjusted;
uint256 token1AmtAdjusted;
uint256 token0DebtInitial;
uint256 token1DebtInitial;
address to;
}
struct PaybackDebtMemory {
uint256 token0AmtAdjusted;
uint256 token1AmtAdjusted;
uint256 token0DebtInitial;
uint256 token1DebtInitial;
}
struct OraclePriceMemory {
uint lowestPrice1by0;
uint highestPrice1by0;
uint oracleSlot;
uint oracleMap;
uint oracle;
}
struct Oracle {
uint twap1by0; // TWAP price
uint lowestPrice1by0; // lowest price point
uint highestPrice1by0; // highest price point
uint twap0by1; // TWAP price
uint lowestPrice0by1; // lowest price point
uint highestPrice0by1; // highest price point
}
struct Implementations {
address shift;
address admin;
address colOperations;
address debtOperations;
address perfectOperationsAndSwapOut;
}
struct ConstantViews {
uint256 dexId;
address liquidity;
address factory;
Implementations implementations;
address deployerContract;
address token0;
address token1;
bytes32 supplyToken0Slot;
bytes32 borrowToken0Slot;
bytes32 supplyToken1Slot;
bytes32 borrowToken1Slot;
bytes32 exchangePriceToken0Slot;
bytes32 exchangePriceToken1Slot;
uint256 oracleMapping;
}
struct ConstantViews2 {
uint token0NumeratorPrecision;
uint token0DenominatorPrecision;
uint token1NumeratorPrecision;
uint token1DenominatorPrecision;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event OwnershipTransferred(address indexed user, address indexed newOwner);
/*//////////////////////////////////////////////////////////////
OWNERSHIP STORAGE
//////////////////////////////////////////////////////////////*/
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
/*//////////////////////////////////////////////////////////////
OWNERSHIP LOGIC
//////////////////////////////////////////////////////////////*/
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}