Source Code
Overview
POL Balance
0 POL
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
BatchLiquidity
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 600 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import { IMarketMakerV1, MarketErrors } from "./IMarketMaker.sol"; import { ArrayMath } from "../Math.sol"; contract BatchLiquidity is MarketErrors { using ArrayMath for uint256[]; /// @notice Removes the collateral liquidity of the transaction sender from /// the specified resolved markets. The transaction reverts if any of these /// market was not resolved. /// @param markets Array of markets to remove the liquidity from. function batchRemoveLiquidity(IMarketMakerV1[] calldata markets, address[] calldata funders) public returns (uint256 collateralRefunded) { for (uint256 i = 0; i < markets.length; i++) { IMarketMakerV1 market = markets[i]; // burns the LP tokens (shares) up to `limitOfFunders` funders // corresponding collateral liquidity to him. (, uint256 collateralRefunded_) = market.removeAllCollateralFunding(funders); collateralRefunded += collateralRefunded_; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import { MarketErrors } from "./MarketErrors.sol"; import { IFundingPoolV1 } from "../funding/IFundingPoolV1.sol"; import { IUpdateFairPrices } from "./IUpdateFairPrices.sol"; /// @dev Interface evolution is done by creating new versions of the interfaces /// and making sure that the derived MarketMaker supports all of them. /// Alternatively we could have gone with breaking the interface down into each /// function one by one and checking each function selector. This would /// introduce a lot more code in `supportsInterface` which is called often, so /// it's easier to keep track of incremental evolution than all the constituent /// pieces interface IMarketMakerV1 is IFundingPoolV1, IUpdateFairPrices, MarketErrors { event MarketBuy( address indexed buyer, uint256 investmentAmount, uint256 feeAmount, uint256 indexed outcomeIndex, uint256 outcomeTokensBought ); event MarketSell( address indexed seller, uint256 returnAmount, uint256 feeAmount, uint256 indexed outcomeIndex, uint256 outcomeTokensSold ); event MarketSpontaneousPrices(uint256[] spontaneousPrices); function removeFunding(uint256 sharesToBurn) external returns (uint256 collateral, uint256[] memory sendAmounts); function buyFor(address receiver, uint256 investmentAmount, uint256 outcomeIndex, uint256 minOutcomeTokensToBuy) external returns (uint256 outcomeTokensBought, uint256 feeAmount, uint256[] memory spontaneousPrices); function buy(uint256 investmentAmount, uint256 outcomeIndex, uint256 minOutcomeTokensToBuy) external returns (uint256 outcomeTokensBought, uint256 feeAmount, uint256[] memory spontaneousPrices); function sell(uint256 returnAmount, uint256 outcomeIndex, uint256 maxOutcomeTokensToSell) external returns (uint256 outcomeTokensSold); function removeCollateralFundingOf(address ownerAndReceiver, uint256 sharesToBurn) external returns (uint256[] memory sendAmounts, uint256 collateral); function removeAllCollateralFunding(address[] calldata funders) external returns (uint256 totalSharesBurnt, uint256 totalCollateralRemoved); function isHalted() external view returns (bool); function calcBuyAmount(uint256 investmentAmount, uint256 outcomeIndex) external view returns (uint256 outcomeTokensBought, uint256 feeAmount, uint256[] memory spontaneousPrices); function calcSellAmount(uint256 returnAmount, uint256 outcomeIndex) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; // Note on libraries. If any functions are not `internal`, then contracts that // use the libraries, must be linked. library ArrayMath { function sum(uint256[] memory values) internal pure returns (uint256) { uint256 result = 0; for (uint256 i = 0; i < values.length; i++) { result += values[i]; } return result; } } /// @dev Math with saturation/clamping for overflow/underflow handling library ClampedMath { /// @dev min(upper, max(lower, x)) function clampBetween(uint256 x, uint256 lower, uint256 upper) internal pure returns (uint256) { unchecked { return x < lower ? lower : (x > upper ? upper : x); } } /// @dev max(0, a - b) function subClamp(uint256 a, uint256 b) internal pure returns (uint256) { unchecked { return a > b ? a - b : 0; } } /// @dev min(type(uint256).max, max(0, a + b)) function addClamp(uint256 a, int256 b) internal pure returns (uint256) { unchecked { if (b < 0) { // The absolute value of type(int256).min is not representable // in int256, so have to dance about with the + 1 uint256 positiveB = uint256(-(b + 1)) + 1; return (a > positiveB) ? (a - positiveB) : 0; } else { return type(uint256).max - a > uint256(b) ? a + uint256(b) : type(uint256).max; } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import { AmmErrors } from "./AmmErrors.sol"; import { FundingErrors } from "../funding/FundingErrors.sol"; interface MarketErrors is AmmErrors, FundingErrors { error MarketHalted(); error MarketUndecided(); // Buy error InvalidInvestmentAmount(); error MinimumBuyAmountNotReached(); error FeesConsumeInvestment(); // Sell error InvalidReturnAmount(); error MaximumSellAmountExceeded(); error InvestmentDrainsPool(); error OperationNotSupported(); error CanOnlyBeFundedByParent(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import { FundingErrors } from "./FundingErrors.sol"; interface FundingPoolEvents { /// @notice Collateral is added to the liquidity pool /// @param sender the account that initiated and supplied the collateral for the funding /// @param funder the account that receives the liquidity pool shares /// @param collateralAdded the quantity of collateral supplied to the pool /// @param sharesMinted the quantity of liquidity pool shares created as sa result of the funding event FundingAdded(address indexed sender, address indexed funder, uint256 collateralAdded, uint256 sharesMinted); /// @notice Funding is removed as a mix of tokens and collateral /// @param funder the owner of liquidity pool shares /// @param collateralRemoved the quantity of collateral removed from the pool proportional to funder's shares /// @param tokensRemoved the quantity of tokens removed from the pool proportional to funder's shares. Can be empty /// @param sharesBurnt the quantity of liquidity pool shares burnt event FundingRemoved( address indexed funder, uint256 collateralRemoved, uint256[] tokensRemoved, uint256 sharesBurnt ); /// @notice Funding is removed as a specific token, referred to by an id /// @param funder the owner of liquidity pool shares /// @param tokenId an id that identifies a single asset token in the pool. Up to the pool to decide the meaning of the id /// @param tokensRemoved the quantity of a token removed from the pool /// @param sharesBurnt the quantity of liquidity pool shares burnt event FundingRemovedAsToken( address indexed funder, uint256 indexed tokenId, uint256 tokensRemoved, uint256 sharesBurnt ); /// @notice Some portion of collateral was withdrawn for fee purposes event FeesWithdrawn(address indexed funder, uint256 collateralRemovedFromFees); /// @notice Some portion of collateral was retained for fee purposes event FeesRetained(uint256 collateralAddedToFees); } /// @dev A funding pool deals with 3 different assets: /// - collateral with which to make investments (ERC20 tokens of general usage, e.g. USDT, USDC, DAI, etc.) /// - shares which represent the stake in the fund (ERC20 tokens minted and burned by the funding pool) /// - tokens that are the actual investments (e.g. ERC1155 conditional tokens) interface IFundingPoolV1 is IERC20Upgradeable, FundingErrors, FundingPoolEvents { /// @notice Funds the market with collateral from the sender /// @param collateralAdded Amount of funds from the sender to transfer to the market function addFunding(uint256 collateralAdded) external returns (uint256 sharesMinted); /// @notice Funds the market on behalf of receiver. /// @param receiver Account that receives LP tokens. /// @param collateralAdded Amount of funds from the sender to transfer to the market function addFundingFor(address receiver, uint256 collateralAdded) external returns (uint256 sharesMinted); /// @notice Withdraws the fees from a particular liquidity provider. /// @param funder Account address to withdraw its available fees. function withdrawFees(address funder) external returns (uint256 collateralRemovedFromFees); /// @notice Returns the amount of fee in collateral to be withdrawn by the liquidity providers. /// @param account Account address to check for fees available. function feesWithdrawableBy(address account) external view returns (uint256 collateralFees); /// @notice How much collateral is available that is not set aside for fees function reserves() external view returns (uint256 collateral); /// @notice Returns the current collected fees on this market. function collectedFees() external view returns (uint256 collateralFees); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface UpdateFairPricesEvents { event MarketPricesUpdated(uint256[] fairPriceDecimals); event MarketMinPriceUpdated(uint128 minPriceDecimal); } interface IUpdateFairPrices is UpdateFairPricesEvents { function updateFairPrices(uint256[] calldata fairPriceDecimals) external; function updateMinPrice(uint128 minPriceDecimal) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface AmmErrors { error InvalidOutcomeIndex(); error NoLiquidityAvailable(); error BalancePriceLengthMismatch(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface FundingErrors { error InvalidFundingAmount(); error InvalidBurnAmount(); error InvalidReceiverAddress(); error PoolValueZero(); /// @dev Fee is is or exceeds 100% error InvalidFee(); /// @dev Trying to retain fees that exceed the current reserves error FeesExceedReserves(); /// @dev Trying to unlock more fees than currently collected error FeesExceedCollected(); /// @dev Funding is so large, that it may lead to overflow errors in future /// actions error ExcessiveFunding(); /// @dev Collateral ERC20 decimals exceed 18, leading to potential overflows error ExcessiveCollateralDecimals(); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@prb/math/=lib/prb-math/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "upgrade-scripts/=lib/upgrade-scripts/src/", "UDS/=lib/upgrade-scripts/lib/UDS/src/", "@prb/test/=lib/prb-math/node_modules/@prb/test/", "futils/=lib/upgrade-scripts/lib/UDS/lib/futils/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "prb-math/=lib/prb-math/src/" ], "optimizer": { "enabled": true, "runs": 600 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
[{"inputs":[],"name":"BalancePriceLengthMismatch","type":"error"},{"inputs":[],"name":"CanOnlyBeFundedByParent","type":"error"},{"inputs":[],"name":"ExcessiveCollateralDecimals","type":"error"},{"inputs":[],"name":"ExcessiveFunding","type":"error"},{"inputs":[],"name":"FeesConsumeInvestment","type":"error"},{"inputs":[],"name":"FeesExceedCollected","type":"error"},{"inputs":[],"name":"FeesExceedReserves","type":"error"},{"inputs":[],"name":"InvalidBurnAmount","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"InvalidFundingAmount","type":"error"},{"inputs":[],"name":"InvalidInvestmentAmount","type":"error"},{"inputs":[],"name":"InvalidOutcomeIndex","type":"error"},{"inputs":[],"name":"InvalidReceiverAddress","type":"error"},{"inputs":[],"name":"InvalidReturnAmount","type":"error"},{"inputs":[],"name":"InvestmentDrainsPool","type":"error"},{"inputs":[],"name":"MarketHalted","type":"error"},{"inputs":[],"name":"MarketUndecided","type":"error"},{"inputs":[],"name":"MaximumSellAmountExceeded","type":"error"},{"inputs":[],"name":"MinimumBuyAmountNotReached","type":"error"},{"inputs":[],"name":"NoLiquidityAvailable","type":"error"},{"inputs":[],"name":"OperationNotSupported","type":"error"},{"inputs":[],"name":"PoolValueZero","type":"error"},{"inputs":[{"internalType":"contract IMarketMakerV1[]","name":"markets","type":"address[]"},{"internalType":"address[]","name":"funders","type":"address[]"}],"name":"batchRemoveLiquidity","outputs":[{"internalType":"uint256","name":"collateralRefunded","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50610326806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f2ff99df14610030575b600080fd5b61004361003e366004610178565b610055565b60405190815260200160405180910390f35b6000805b84811015610123576000868683818110610075576100756101e4565b905060200201602081019061008a9190610212565b90506000816001600160a01b031663480fa82e87876040518363ffffffff1660e01b81526004016100bc929190610236565b60408051808303816000875af11580156100da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fe9190610284565b915061010c905081856102be565b93505050808061011b906102d7565b915050610059565b50949350505050565b60008083601f84011261013e57600080fd5b50813567ffffffffffffffff81111561015657600080fd5b6020830191508360208260051b850101111561017157600080fd5b9250929050565b6000806000806040858703121561018e57600080fd5b843567ffffffffffffffff808211156101a657600080fd5b6101b28883890161012c565b909650945060208701359150808211156101cb57600080fd5b506101d88782880161012c565b95989497509550505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038116811461020f57600080fd5b50565b60006020828403121561022457600080fd5b813561022f816101fa565b9392505050565b60208082528181018390526000908460408401835b8681101561027957823561025e816101fa565b6001600160a01b03168252918301919083019060010161024b565b509695505050505050565b6000806040838503121561029757600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b808201808211156102d1576102d16102a8565b92915050565b6000600182016102e9576102e96102a8565b506001019056fea2646970667358221220dbaf359e2998cea7b0584b0c610e31cae0c491d44b75ada2c5aa2d2319e8323064736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f2ff99df14610030575b600080fd5b61004361003e366004610178565b610055565b60405190815260200160405180910390f35b6000805b84811015610123576000868683818110610075576100756101e4565b905060200201602081019061008a9190610212565b90506000816001600160a01b031663480fa82e87876040518363ffffffff1660e01b81526004016100bc929190610236565b60408051808303816000875af11580156100da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fe9190610284565b915061010c905081856102be565b93505050808061011b906102d7565b915050610059565b50949350505050565b60008083601f84011261013e57600080fd5b50813567ffffffffffffffff81111561015657600080fd5b6020830191508360208260051b850101111561017157600080fd5b9250929050565b6000806000806040858703121561018e57600080fd5b843567ffffffffffffffff808211156101a657600080fd5b6101b28883890161012c565b909650945060208701359150808211156101cb57600080fd5b506101d88782880161012c565b95989497509550505050565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b038116811461020f57600080fd5b50565b60006020828403121561022457600080fd5b813561022f816101fa565b9392505050565b60208082528181018390526000908460408401835b8681101561027957823561025e816101fa565b6001600160a01b03168252918301919083019060010161024b565b509695505050505050565b6000806040838503121561029757600080fd5b505080516020909101519092909150565b634e487b7160e01b600052601160045260246000fd5b808201808211156102d1576102d16102a8565b92915050565b6000600182016102e9576102e96102a8565b506001019056fea2646970667358221220dbaf359e2998cea7b0584b0c610e31cae0c491d44b75ada2c5aa2d2319e8323064736f6c63430008130033
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.