文件 1 的 29:AccessControl.sol
pragma solidity >=0.6.0 <0.8.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) public view returns (bool) {
return _roles[role].members.contains(account);
}
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 29:Address.sol
pragma solidity >=0.6.2 <0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 3 的 29:AuctionHouse.sol
pragma solidity =0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts/GSN/Context.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "./Staged.sol";
import "./AuctionHouseMath.sol";
import "./interfaces/IAuctionHouse.sol";
import "../funds/interfaces/basket/IBasketReader.sol";
import "../oracle/interfaces/ITwap.sol";
import "../policy/interfaces/IMonetaryPolicy.sol";
import "../tokens/interfaces/ISupplyControlledERC20.sol";
import "../lib/BasisMath.sol";
import "../lib/BlockNumber.sol";
import "../lib/Recoverable.sol";
import "../external-lib/SafeDecimalMath.sol";
import "../tokens/SafeSupplyControlledERC20.sol";
contract AuctionHouse is
IAuctionHouse,
BlockNumber,
AuctionHouseMath,
AccessControl,
Staged,
Recoverable
{
using SafeMath for uint256;
using SafeDecimalMath for uint256;
using SafeERC20 for IERC20;
using SafeERC20 for ISupplyControlledERC20;
using SafeSupplyControlledERC20 for ISupplyControlledERC20;
using BasisMath for uint256;
bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
IERC20 internal immutable weth;
ISupplyControlledERC20 internal immutable bank;
ISupplyControlledERC20 internal immutable float;
IBasketReader internal immutable basket;
IMonetaryPolicy internal monetaryPolicy;
ITwap internal bankEthOracle;
ITwap internal floatEthOracle;
uint16 public override buffer = 10_00;
uint16 public override protocolFee = 5_00;
uint32 public override allowanceCap = 10_00;
uint64 public override round;
bool public shouldUpdatePolicy = true;
mapping(uint64 => Auction) public override auctions;
constructor(
address _weth,
address _bank,
address _float,
address _basket,
address _monetaryPolicy,
address _gov,
address _bankEthOracle,
address _floatEthOracle,
uint16 _auctionDuration,
uint32 _auctionCooldown,
uint256 _firstAuctionBlock
) Staged(_auctionDuration, _auctionCooldown, _firstAuctionBlock) {
weth = IERC20(_weth);
bank = ISupplyControlledERC20(_bank);
float = ISupplyControlledERC20(_float);
basket = IBasketReader(_basket);
monetaryPolicy = IMonetaryPolicy(_monetaryPolicy);
floatEthOracle = ITwap(_floatEthOracle);
bankEthOracle = ITwap(_bankEthOracle);
emit ModifyParameters("monetaryPolicy", _monetaryPolicy);
emit ModifyParameters("floatEthOracle", _floatEthOracle);
emit ModifyParameters("bankEthOracle", _bankEthOracle);
emit ModifyParameters("auctionDuration", _auctionDuration);
emit ModifyParameters("auctionCooldown", _auctionCooldown);
emit ModifyParameters("lastAuctionBlock", lastAuctionBlock);
emit ModifyParameters("buffer", buffer);
emit ModifyParameters("protocolFee", protocolFee);
emit ModifyParameters("allowanceCap", allowanceCap);
_setupRole(DEFAULT_ADMIN_ROLE, _gov);
_setupRole(GOVERNANCE_ROLE, _gov);
_setupRole(RECOVER_ROLE, _gov);
}
modifier onlyGovernance {
require(
hasRole(GOVERNANCE_ROLE, _msgSender()),
"AuctionHouse/GovernanceRole"
);
_;
}
modifier inExpansion {
require(
latestAuction().stabilisationCase == Cases.Up ||
latestAuction().stabilisationCase == Cases.Restock,
"AuctionHouse/NotInExpansion"
);
_;
}
modifier inContraction {
require(
latestAuction().stabilisationCase == Cases.Confidence ||
latestAuction().stabilisationCase == Cases.Down,
"AuctionHouse/NotInContraction"
);
_;
}
function price()
public
view
override(IAuctionHouseDerivedState)
returns (uint256 wethPrice, uint256 bankPrice)
{
Auction memory _latestAuction = latestAuction();
uint256 _step = step();
wethPrice = lerp(
_latestAuction.startWethPrice,
_latestAuction.endWethPrice,
_step,
auctionDuration
);
bankPrice = lerp(
_latestAuction.startBankPrice,
_latestAuction.endBankPrice,
_step,
auctionDuration
);
return (wethPrice, bankPrice);
}
function step()
public
view
override(IAuctionHouseDerivedState)
atStage(Stages.AuctionActive)
returns (uint256)
{
return _blockNumber() - lastAuctionBlock;
}
function _startPrice(
bool expansion,
Cases stabilisationCase,
uint256 targetFloatInEth,
uint256 marketFloatInEth,
uint256 bankInEth,
uint256 basketFactor
) internal view returns (uint256 wethStart, uint256 bankStart) {
uint256 bufferedMarketPrice =
_bufferedMarketPrice(expansion, marketFloatInEth);
if (stabilisationCase == Cases.Up) {
uint256 bankProportion =
bufferedMarketPrice.sub(targetFloatInEth).divideDecimalRoundPrecise(
bankInEth
);
return (targetFloatInEth, bankProportion);
}
if (
stabilisationCase == Cases.Restock ||
stabilisationCase == Cases.Confidence
) {
return (bufferedMarketPrice, 0);
}
assert(stabilisationCase == Cases.Down);
assert(basketFactor < SafeDecimalMath.PRECISE_UNIT);
uint256 invertedBasketFactor =
SafeDecimalMath.PRECISE_UNIT.sub(basketFactor);
uint256 basketFactorAdjustedEth =
bufferedMarketPrice.multiplyDecimalRoundPrecise(basketFactor);
uint256 basketFactorAdjustedBank =
bufferedMarketPrice.mul(invertedBasketFactor).div(bankInEth);
return (basketFactorAdjustedEth, basketFactorAdjustedBank);
}
function _endPrice(
Cases stabilisationCase,
uint256 targetFloatInEth,
uint256 bankInEth,
uint256 basketFactor
) internal pure returns (uint256 wethEnd, uint256 bankEnd) {
if (stabilisationCase == Cases.Down) {
assert(basketFactor < SafeDecimalMath.PRECISE_UNIT);
uint256 invertedBasketFactor =
SafeDecimalMath.PRECISE_UNIT.sub(basketFactor);
uint256 basketFactorAdjustedEth =
targetFloatInEth.multiplyDecimalRoundPrecise(basketFactor);
uint256 basketFactorAdjustedBank =
targetFloatInEth.mul(invertedBasketFactor).div(bankInEth);
return (basketFactorAdjustedEth, basketFactorAdjustedBank);
}
return (targetFloatInEth, 0);
}
function latestAuction()
public
view
override(IAuctionHouseDerivedState)
returns (Auction memory)
{
return auctions[round];
}
function _bufferedMarketPrice(bool expansion, uint256 marketPrice)
internal
view
returns (uint256)
{
uint256 factor =
expansion
? BasisMath.FULL_PERCENT.add(buffer)
: BasisMath.FULL_PERCENT.sub(buffer);
return marketPrice.percentageOf(factor);
}
function _currentCase(bool expansion, uint256 basketFactor)
internal
pure
returns (Cases)
{
bool underlyingDemand = basketFactor >= SafeDecimalMath.PRECISE_UNIT;
if (expansion) {
return underlyingDemand ? Cases.Up : Cases.Restock;
}
return underlyingDemand ? Cases.Confidence : Cases.Down;
}
function start()
external
override(IAuctionHouseActions)
timedTransition
atStage(Stages.AuctionPending)
returns (uint64 newRound)
{
bankEthOracle.update(address(bank), address(weth));
floatEthOracle.update(address(float), address(weth));
uint256 frozenBankInEth =
bankEthOracle.consult(
address(bank),
SafeDecimalMath.PRECISE_UNIT,
address(weth)
);
uint256 frozenFloatInEth =
floatEthOracle.consult(
address(float),
SafeDecimalMath.PRECISE_UNIT,
address(weth)
);
if (round != 0 && shouldUpdatePolicy) {
uint256 oldTargetPriceInEth = monetaryPolicy.consult();
uint256 oldBasketFactor = basket.getBasketFactor(oldTargetPriceInEth);
monetaryPolicy.updateGivenAuctionResults(
round,
lastAuctionBlock,
frozenFloatInEth,
oldBasketFactor
);
}
round++;
uint256 frozenTargetPriceInEth = monetaryPolicy.consult();
require(frozenTargetPriceInEth != 0, "AuctionHouse/TargetSenseCheck");
require(frozenBankInEth != 0, "AuctionHouse/BankSenseCheck");
require(frozenFloatInEth != 0, "AuctionHouse/FloatSenseCheck");
uint256 basketFactor = basket.getBasketFactor(frozenTargetPriceInEth);
bool expansion = frozenFloatInEth >= frozenTargetPriceInEth;
Cases stabilisationCase = _currentCase(expansion, basketFactor);
(uint256 wethStart, uint256 bankStart) =
_startPrice(
expansion,
stabilisationCase,
frozenTargetPriceInEth,
frozenFloatInEth,
frozenBankInEth,
basketFactor
);
(uint256 wethEnd, uint256 bankEnd) =
_endPrice(
stabilisationCase,
frozenTargetPriceInEth,
frozenBankInEth,
basketFactor
);
uint256 allowance =
AuctionHouseMath.allowance(
expansion,
allowanceCap,
float.totalSupply(),
frozenFloatInEth,
frozenTargetPriceInEth
);
require(allowance != 0, "AuctionHouse/NoAllowance");
auctions[round].stabilisationCase = stabilisationCase;
auctions[round].targetFloatInEth = frozenTargetPriceInEth;
auctions[round].marketFloatInEth = frozenFloatInEth;
auctions[round].bankInEth = frozenBankInEth;
auctions[round].basketFactor = basketFactor;
auctions[round].allowance = allowance;
auctions[round].startWethPrice = wethStart;
auctions[round].startBankPrice = bankStart;
auctions[round].endWethPrice = wethEnd;
auctions[round].endBankPrice = bankEnd;
lastAuctionBlock = _blockNumber();
_setStage(Stages.AuctionActive);
emit NewAuction(round, allowance, frozenTargetPriceInEth, lastAuctionBlock);
return round;
}
function _updateDelta(uint256 floatDelta) internal {
Auction memory _currentAuction = latestAuction();
require(
floatDelta <= _currentAuction.allowance.sub(_currentAuction.delta),
"AuctionHouse/WithinAllowedDelta"
);
auctions[round].delta = _currentAuction.delta.add(floatDelta);
}
function buy(
uint256 wethInMax,
uint256 bankInMax,
uint256 floatOutMin,
address to,
uint256 deadline
)
external
override(IAuctionHouseActions)
timedTransition
atStage(Stages.AuctionActive)
inExpansion
returns (
uint256 usedWethIn,
uint256 usedBankIn,
uint256 usedFloatOut
)
{
require(block.timestamp <= deadline, "AuctionHouse/TransactionTooOld");
(uint256 wethPrice, uint256 bankPrice) = price();
usedFloatOut = Math.min(
wethInMax.divideDecimalRoundPrecise(wethPrice),
bankPrice == 0
? type(uint256).max
: bankInMax.divideDecimalRoundPrecise(bankPrice)
);
require(usedFloatOut != 0, "AuctionHouse/ZeroFloatBought");
require(usedFloatOut >= floatOutMin, "AuctionHouse/RequestedTooMuch");
usedWethIn = wethPrice.multiplyDecimalRoundPrecise(usedFloatOut);
usedBankIn = bankPrice.multiplyDecimalRoundPrecise(usedFloatOut);
require(wethInMax >= usedWethIn, "AuctionHouse/MinimumWeth");
require(bankInMax >= usedBankIn, "AuctionHouse/MinimumBank");
_updateDelta(usedFloatOut);
emit Buy(round, _msgSender(), usedWethIn, usedBankIn, usedFloatOut);
_interactBuy(usedWethIn, usedBankIn, usedFloatOut, to);
return (usedWethIn, usedBankIn, usedFloatOut);
}
function _interactBuy(
uint256 usedWethIn,
uint256 usedBankIn,
uint256 usedFloatOut,
address to
) internal {
weth.safeTransferFrom(_msgSender(), address(basket), usedWethIn);
if (usedBankIn != 0) {
(uint256 bankToSave, uint256 bankToBurn) =
usedBankIn.splitBy(protocolFee);
bank.safeTransferFrom(_msgSender(), address(this), bankToSave);
bank.safeBurnFrom(_msgSender(), bankToBurn);
}
float.safeMint(to, usedFloatOut);
}
function sell(
uint256 floatIn,
uint256 wethOutMin,
uint256 bankOutMin,
address to,
uint256 deadline
)
external
override(IAuctionHouseActions)
timedTransition
atStage(Stages.AuctionActive)
inContraction
returns (
uint256 usedfloatIn,
uint256 usedWethOut,
uint256 usedBankOut
)
{
require(block.timestamp <= deadline, "AuctionHouse/TransactionTooOld");
require(floatIn != 0, "AuctionHouse/ZeroFloatSold");
(uint256 wethPrice, uint256 bankPrice) = price();
usedWethOut = wethPrice.multiplyDecimalRoundPrecise(floatIn);
usedBankOut = bankPrice.multiplyDecimalRoundPrecise(floatIn);
require(wethOutMin <= usedWethOut, "AuctionHouse/ExpectedTooMuchWeth");
require(bankOutMin <= usedBankOut, "AuctionHouse/ExpectedTooMuchBank");
_updateDelta(floatIn);
emit Sell(round, _msgSender(), floatIn, usedWethOut, usedBankOut);
_interactSell(floatIn, usedWethOut, usedBankOut, to);
return (floatIn, usedWethOut, usedBankOut);
}
function _interactSell(
uint256 floatIn,
uint256 usedWethOut,
uint256 usedBankOut,
address to
) internal {
float.safeBurnFrom(_msgSender(), floatIn);
if (usedWethOut != 0) {
weth.safeTransferFrom(address(basket), to, usedWethOut);
}
if (usedBankOut != 0) {
bank.safeMint(to, usedBankOut);
}
}
function modifyParameters(bytes32 parameter, uint256 data)
external
override(IAuctionHouseGovernedActions)
onlyGovernance
{
if (parameter == "auctionDuration") {
require(data <= type(uint16).max, "AuctionHouse/ModADMax");
require(data != 0, "AuctionHouse/ModADZero");
auctionDuration = uint16(data);
} else if (parameter == "auctionCooldown") {
require(data <= type(uint32).max, "AuctionHouse/ModCMax");
auctionCooldown = uint32(data);
} else if (parameter == "buffer") {
require(data <= 10 * BasisMath.FULL_PERCENT, "AuctionHouse/ModBMax");
buffer = uint16(data);
} else if (parameter == "protocolFee") {
require(data <= BasisMath.FULL_PERCENT, "AuctionHouse/ModPFMax");
protocolFee = uint16(data);
} else if (parameter == "allowanceCap") {
require(data <= type(uint32).max, "AuctionHouse/ModACMax");
require(data != 0, "AuctionHouse/ModACMin");
allowanceCap = uint32(data);
} else if (parameter == "shouldUpdatePolicy") {
require(data == 1 || data == 0, "AuctionHouse/ModUP");
shouldUpdatePolicy = data == 1;
} else if (parameter == "lastAuctionBlock") {
require(data <= block.number + 2e5, "AuctionHouse/ModLABMax");
require(data != 0, "AuctionHouse/ModLABMin");
lastAuctionBlock = data;
} else revert("AuctionHouse/InvalidParameter");
emit ModifyParameters(parameter, data);
}
function modifyParameters(bytes32 parameter, address data)
external
override(IAuctionHouseGovernedActions)
onlyGovernance
{
if (parameter == "monetaryPolicy") {
monetaryPolicy = IMonetaryPolicy(data);
} else if (parameter == "bankEthOracle") {
bankEthOracle = ITwap(data);
} else if (parameter == "floatEthOracle") {
floatEthOracle = ITwap(data);
} else revert("AuctionHouse/InvalidParameter");
emit ModifyParameters(parameter, data);
}
}
文件 4 的 29:AuctionHouseMath.sol
pragma solidity =0.7.6;
import "@openzeppelin/contracts/math/Math.sol";
import "../lib/BasisMath.sol";
import "../external-lib/SafeDecimalMath.sol";
contract AuctionHouseMath {
using SafeMath for uint256;
using SafeDecimalMath for uint256;
using BasisMath for uint256;
function allowance(
bool expansion,
uint256 capBasisPoint,
uint256 floatSupply,
uint256 marketFloatPrice,
uint256 targetFloatPrice
) internal pure returns (uint256) {
uint256 targetSupply =
marketFloatPrice.mul(floatSupply).div(targetFloatPrice);
uint256 allowanceForAdjustment =
expansion ? targetSupply.sub(floatSupply) : floatSupply.sub(targetSupply);
uint256 allowanceByCap = floatSupply.percentageOf(capBasisPoint);
return Math.min(allowanceForAdjustment, allowanceByCap);
}
function lerp(
uint256 start,
uint256 end,
uint256 step,
uint256 duration
) internal pure returns (uint256 result) {
require(duration != 0, "AuctionHouseMath/ZeroDuration");
require(step <= duration, "AuctionHouseMath/InvalidStep");
require(start <= 10**49, "AuctionHouseMath/StartTooLarge");
require(end <= 10**49, "AuctionHouseMath/EndTooLarge");
uint256 t = step.divideDecimalRoundPrecise(duration);
return
result = end.multiplyDecimalRoundPrecise(t).add(start).sub(
start.multiplyDecimalRoundPrecise(t)
);
}
}
文件 5 的 29:BasisMath.sol
pragma solidity =0.7.6;
library BasisMath {
uint256 internal constant FULL_PERCENT = 1e4;
uint256 internal constant HALF_ONCE_SCALED = FULL_PERCENT / 2;
function percentageOf(uint256 self, uint256 percentage)
internal
pure
returns (uint256 pct)
{
if (self == 0 || percentage == 0) {
pct = 0;
} else {
require(
self <= (type(uint256).max - HALF_ONCE_SCALED) / percentage,
"BasisMath/Overflow"
);
pct = (self * percentage + HALF_ONCE_SCALED) / FULL_PERCENT;
}
}
function splitBy(uint256 self, uint256 percentage)
internal
pure
returns (uint256 pct, uint256 rem)
{
require(percentage <= FULL_PERCENT, "BasisMath/ExcessPercentage");
pct = percentageOf(self, percentage);
rem = self - pct;
}
}
文件 6 的 29:BlockNumber.sol
pragma solidity =0.7.6;
abstract contract BlockNumber {
function _blockNumber() internal view virtual returns (uint256) {
return block.number;
}
}
文件 7 的 29:Context.sol
pragma solidity >=0.6.0 <0.8.0;
import "../utils/Context.sol";
文件 8 的 29:EnumerableSet.sol
pragma solidity >=0.6.0 <0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = toDeleteIndex + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 9 的 29:IAuction.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
import "./ICases.sol";
interface IAuction is ICases {
struct Auction {
Cases stabilisationCase;
uint256 targetFloatInEth;
uint256 marketFloatInEth;
uint256 bankInEth;
uint256 startWethPrice;
uint256 startBankPrice;
uint256 endWethPrice;
uint256 endBankPrice;
uint256 basketFactor;
uint256 delta;
uint256 allowance;
}
}
文件 10 的 29:IAuctionHouse.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
import "./ah/IAuctionHouseState.sol";
import "./ah/IAuctionHouseVariables.sol";
import "./ah/IAuctionHouseDerivedState.sol";
import "./ah/IAuctionHouseActions.sol";
import "./ah/IAuctionHouseGovernedActions.sol";
import "./ah/IAuctionHouseEvents.sol";
interface IAuctionHouse is
IAuctionHouseState,
IAuctionHouseVariables,
IAuctionHouseDerivedState,
IAuctionHouseActions,
IAuctionHouseGovernedActions,
IAuctionHouseEvents
{
}
文件 11 的 29:IAuctionHouseActions.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
interface IAuctionHouseActions {
function start() external returns (uint64 newRound);
function buy(
uint256 wethInMax,
uint256 bankInMax,
uint256 floatOutMin,
address to,
uint256 deadline
)
external
returns (
uint256 usedWethIn,
uint256 usedBankIn,
uint256 usedFloatOut
);
function sell(
uint256 floatIn,
uint256 wethOutMin,
uint256 bankOutMin,
address to,
uint256 deadline
)
external
returns (
uint256 usedfloatIn,
uint256 usedWethOut,
uint256 usedBankOut
);
}
文件 12 的 29:IAuctionHouseDerivedState.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
import "./IAuction.sol";
interface IAuctionHouseDerivedState is IAuction {
function price() external view returns (uint256 wethPrice, uint256 bankPrice);
function step() external view returns (uint256);
function latestAuction() external view returns (Auction memory);
}
文件 13 的 29:IAuctionHouseEvents.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
interface IAuctionHouseEvents {
event NewAuction(
uint256 indexed round,
uint256 allowance,
uint256 targetFloatInEth,
uint256 startBlock
);
event Buy(
uint256 indexed round,
address indexed buyer,
uint256 wethIn,
uint256 bankIn,
uint256 floatOut
);
event Sell(
uint256 indexed round,
address indexed seller,
uint256 floatIn,
uint256 wethOut,
uint256 bankOut
);
event ModifyParameters(bytes32 parameter, uint256 data);
event ModifyParameters(bytes32 parameter, address data);
}
文件 14 的 29:IAuctionHouseGovernedActions.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
interface IAuctionHouseGovernedActions {
function modifyParameters(bytes32 parameter, uint256 data) external;
function modifyParameters(bytes32 parameter, address data) external;
}
文件 15 的 29:IAuctionHouseState.sol
pragma solidity >=0.5.0;
interface IAuctionHouseState {
function buffer() external view returns (uint16);
function protocolFee() external view returns (uint16);
function allowanceCap() external view returns (uint32);
}
文件 16 的 29:IAuctionHouseVariables.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
import "./ICases.sol";
interface IAuctionHouseVariables is ICases {
function round() external view returns (uint64);
function auctions(uint64 roundNumber)
external
view
returns (
Cases stabilisationCase,
uint256 targetFloatInEth,
uint256 marketFloatInEth,
uint256 bankInEth,
uint256 startWethPrice,
uint256 startBankPrice,
uint256 endWethPrice,
uint256 endBankPrice,
uint256 basketFactor,
uint256 delta,
uint256 allowance
);
}
文件 17 的 29:IBasketReader.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
interface IBasketReader {
function underlying() external view returns (address);
function getBasketFactor(uint256 targetPriceInUnderlying)
external
view
returns (uint256 basketFactor);
}
文件 18 的 29:ICases.sol
pragma solidity ^0.7.6;
pragma abicoder v2;
interface ICases {
enum Cases {Up, Restock, Confidence, Down}
}
文件 19 的 29:IERC20.sol
pragma solidity >=0.6.0 <0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 20 的 29:IMonetaryPolicy.sol
pragma solidity >=0.7.0 <0.8.0;
interface IMonetaryPolicy {
function consult() external view returns (uint256 targetPriceInEth);
function updateGivenAuctionResults(
uint256 round,
uint256 lastAuctionBlock,
uint256 floatMarketPrice,
uint256 basketFactor
) external returns (uint256 targetPriceInEth);
}
文件 21 的 29:ISupplyControlledERC20.sol
pragma solidity >=0.5.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ISupplyControlledERC20 is IERC20 {
function mint(address to, uint256 amount) external;
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
}
文件 22 的 29:ITwap.sol
pragma solidity >=0.7.0 <0.8.0;
interface ITwap {
function consult(
address tokenIn,
uint256 amountIn,
address tokenOut
) external view returns (uint256 amountOut);
function updateable(address tokenA, address tokenB)
external
view
returns (bool);
function update(address tokenA, address tokenB) external returns (bool);
}
文件 23 的 29:Math.sol
pragma solidity >=0.6.0 <0.8.0;
library Math {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
文件 24 的 29:Recoverable.sol
pragma solidity =0.7.6;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
abstract contract Recoverable is AccessControl {
using SafeERC20 for IERC20;
using Address for address payable;
bytes32 public constant RECOVER_ROLE = keccak256("RECOVER_ROLE");
event Recovered(address onBehalfOf, address tokenAddress, uint256 amount);
modifier isRecoverer {
require(hasRole(RECOVER_ROLE, _msgSender()), "Recoverable/RecoverRole");
_;
}
function recoverERC20(
address to,
address tokenAddress,
uint256 tokenAmount
) external isRecoverer {
emit Recovered(to, tokenAddress, tokenAmount);
IERC20(tokenAddress).safeTransfer(to, tokenAmount);
}
function recoverETH(address to) external isRecoverer {
uint256 contractBalance = address(this).balance;
emit Recovered(to, address(0), contractBalance);
payable(to).sendValue(contractBalance);
}
}
文件 25 的 29:SafeDecimalMath.sol
pragma solidity ^0.7.6;
import "@openzeppelin/contracts/math/SafeMath.sol";
library SafeDecimalMath {
using SafeMath for uint256;
uint8 public constant decimals = 18;
uint8 public constant highPrecisionDecimals = 27;
uint256 public constant UNIT = 10**uint256(decimals);
uint256 public constant PRECISE_UNIT = 10**uint256(highPrecisionDecimals);
uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR =
10**uint256(highPrecisionDecimals - decimals);
function unit() external pure returns (uint256) {
return UNIT;
}
function preciseUnit() external pure returns (uint256) {
return PRECISE_UNIT;
}
function multiplyDecimal(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return x.mul(y) / UNIT;
}
function _multiplyDecimalRound(
uint256 x,
uint256 y,
uint256 precisionUnit
) private pure returns (uint256) {
uint256 quotientTimesTen = x.mul(y) / (precisionUnit / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
function multiplyDecimalRoundPrecise(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return _multiplyDecimalRound(x, y, PRECISE_UNIT);
}
function multiplyDecimalRound(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return _multiplyDecimalRound(x, y, UNIT);
}
function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(UNIT).div(y);
}
function _divideDecimalRound(
uint256 x,
uint256 y,
uint256 precisionUnit
) private pure returns (uint256) {
uint256 resultTimesTen = x.mul(precisionUnit * 10).div(y);
if (resultTimesTen % 10 >= 5) {
resultTimesTen += 10;
}
return resultTimesTen / 10;
}
function divideDecimalRound(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return _divideDecimalRound(x, y, UNIT);
}
function divideDecimalRoundPrecise(uint256 x, uint256 y)
internal
pure
returns (uint256)
{
return _divideDecimalRound(x, y, PRECISE_UNIT);
}
function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) {
return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
}
function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) {
uint256 quotientTimesTen =
i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen += 10;
}
return quotientTimesTen / 10;
}
}
文件 26 的 29:SafeERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 27 的 29:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 28 的 29:SafeSupplyControlledERC20.sol
pragma solidity =0.7.6;
import "../tokens/interfaces/ISupplyControlledERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
library SafeSupplyControlledERC20 {
using SafeMath for uint256;
using Address for address;
function safeBurnFrom(
ISupplyControlledERC20 token,
address from,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.burnFrom.selector, from, value)
);
}
function safeMint(
ISupplyControlledERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.mint.selector, to, value)
);
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata =
address(token).functionCall(
data,
"SafeSupplyControlled/LowlevelCallFailed"
);
if (returndata.length > 0) {
require(
abi.decode(returndata, (bool)),
"SafeSupplyControlled/ERC20Failed"
);
}
}
}
文件 29 的 29:Staged.sol
pragma solidity =0.7.6;
import "../lib/BlockNumber.sol";
contract Staged is BlockNumber {
enum Stages {AuctionCooling, AuctionPending, AuctionActive}
uint32 internal auctionCooldown;
uint16 internal auctionDuration;
Stages public stage;
uint256 public lastAuctionBlock;
constructor(
uint16 _auctionDuration,
uint32 _auctionCooldown,
uint256 _firstAuctionBlock
) {
require(
_firstAuctionBlock >= _auctionDuration + _auctionCooldown,
"Staged/InvalidAuctionStart"
);
auctionDuration = _auctionDuration;
auctionCooldown = _auctionCooldown;
lastAuctionBlock = _firstAuctionBlock - _auctionDuration - _auctionCooldown;
stage = Stages.AuctionCooling;
}
event StageChanged(uint8 _prevStage, uint8 _newStage);
modifier atStage(Stages _stage) {
require(stage == _stage, "Staged/InvalidStage");
_;
}
modifier timedTransition() {
uint256 _blockNumber = _blockNumber();
if (
stage == Stages.AuctionActive &&
_blockNumber > lastAuctionBlock + auctionDuration
) {
stage = Stages.AuctionCooling;
emit StageChanged(uint8(Stages.AuctionActive), uint8(stage));
}
if (
stage == Stages.AuctionCooling &&
_blockNumber > lastAuctionBlock + auctionDuration + auctionCooldown
) {
stage = Stages.AuctionPending;
emit StageChanged(uint8(Stages.AuctionCooling), uint8(stage));
}
_;
}
function updateStage() external timedTransition returns (Stages) {
return stage;
}
function _setStage(Stages _stage) internal {
Stages priorStage = stage;
stage = _stage;
emit StageChanged(uint8(priorStage), uint8(_stage));
}
}
{
"compilationTarget": {
"contracts/auction/AuctionHouse.sol": "AuctionHouse"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_bank","type":"address"},{"internalType":"address","name":"_float","type":"address"},{"internalType":"address","name":"_basket","type":"address"},{"internalType":"address","name":"_monetaryPolicy","type":"address"},{"internalType":"address","name":"_gov","type":"address"},{"internalType":"address","name":"_bankEthOracle","type":"address"},{"internalType":"address","name":"_floatEthOracle","type":"address"},{"internalType":"uint16","name":"_auctionDuration","type":"uint16"},{"internalType":"uint32","name":"_auctionCooldown","type":"uint32"},{"internalType":"uint256","name":"_firstAuctionBlock","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"wethIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bankIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"floatOut","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"data","type":"uint256"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"address","name":"data","type":"address"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allowance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"targetFloatInEth","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"}],"name":"NewAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"floatIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"wethOut","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bankOut","type":"uint256"}],"name":"Sell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"_prevStage","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"_newStage","type":"uint8"}],"name":"StageChanged","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNANCE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECOVER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowanceCap","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"auctions","outputs":[{"internalType":"enum ICases.Cases","name":"stabilisationCase","type":"uint8"},{"internalType":"uint256","name":"targetFloatInEth","type":"uint256"},{"internalType":"uint256","name":"marketFloatInEth","type":"uint256"},{"internalType":"uint256","name":"bankInEth","type":"uint256"},{"internalType":"uint256","name":"startWethPrice","type":"uint256"},{"internalType":"uint256","name":"startBankPrice","type":"uint256"},{"internalType":"uint256","name":"endWethPrice","type":"uint256"},{"internalType":"uint256","name":"endBankPrice","type":"uint256"},{"internalType":"uint256","name":"basketFactor","type":"uint256"},{"internalType":"uint256","name":"delta","type":"uint256"},{"internalType":"uint256","name":"allowance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buffer","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wethInMax","type":"uint256"},{"internalType":"uint256","name":"bankInMax","type":"uint256"},{"internalType":"uint256","name":"floatOutMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"buy","outputs":[{"internalType":"uint256","name":"usedWethIn","type":"uint256"},{"internalType":"uint256","name":"usedBankIn","type":"uint256"},{"internalType":"uint256","name":"usedFloatOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAuctionBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAuction","outputs":[{"components":[{"internalType":"enum ICases.Cases","name":"stabilisationCase","type":"uint8"},{"internalType":"uint256","name":"targetFloatInEth","type":"uint256"},{"internalType":"uint256","name":"marketFloatInEth","type":"uint256"},{"internalType":"uint256","name":"bankInEth","type":"uint256"},{"internalType":"uint256","name":"startWethPrice","type":"uint256"},{"internalType":"uint256","name":"startBankPrice","type":"uint256"},{"internalType":"uint256","name":"endWethPrice","type":"uint256"},{"internalType":"uint256","name":"endBankPrice","type":"uint256"},{"internalType":"uint256","name":"basketFactor","type":"uint256"},{"internalType":"uint256","name":"delta","type":"uint256"},{"internalType":"uint256","name":"allowance","type":"uint256"}],"internalType":"struct IAuction.Auction","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"address","name":"data","type":"address"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"uint256","name":"data","type":"uint256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"wethPrice","type":"uint256"},{"internalType":"uint256","name":"bankPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"recoverETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"round","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"floatIn","type":"uint256"},{"internalType":"uint256","name":"wethOutMin","type":"uint256"},{"internalType":"uint256","name":"bankOutMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"sell","outputs":[{"internalType":"uint256","name":"usedfloatIn","type":"uint256"},{"internalType":"uint256","name":"usedWethOut","type":"uint256"},{"internalType":"uint256","name":"usedBankOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldUpdatePolicy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stage","outputs":[{"internalType":"enum Staged.Stages","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint64","name":"newRound","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"step","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateStage","outputs":[{"internalType":"enum Staged.Stages","name":"","type":"uint8"}],"stateMutability":"nonpayable","type":"function"}]