Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MarketplaceFacet
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "./Order.sol"; /** * @author Beanjoyer, Malteasy * @title Pod Marketplace v2 **/ contract MarketplaceFacet is Order { /* * Pod Listing */ /* * @notice **LEGACY** */ function createPodListing( uint256 index, uint256 start, uint256 amount, uint24 pricePerPod, uint256 maxHarvestableIndex, uint256 minFillAmount, LibTransfer.To mode ) external payable { _createPodListing( index, start, amount, pricePerPod, maxHarvestableIndex, minFillAmount, mode ); } function createPodListingV2( uint256 index, uint256 start, uint256 amount, uint256 maxHarvestableIndex, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.To mode ) external payable { _createPodListingV2( index, start, amount, maxHarvestableIndex, minFillAmount, pricingFunction, mode ); } // Fill function fillPodListing( PodListing calldata l, uint256 beanAmount, LibTransfer.From mode ) external payable { beanAmount = LibTransfer.transferToken( C.bean(), msg.sender, l.account, beanAmount, mode, l.mode ); _fillListing(l, beanAmount); } function fillPodListingV2( PodListing calldata l, uint256 beanAmount, bytes calldata pricingFunction, LibTransfer.From mode ) external payable { beanAmount = LibTransfer.transferToken( C.bean(), msg.sender, l.account, beanAmount, mode, l.mode ); _fillListingV2(l, beanAmount, pricingFunction); } // Cancel function cancelPodListing(uint256 index) external payable { _cancelPodListing(msg.sender, index); } // Get function podListing(uint256 index) external view returns (bytes32) { return s.podListings[index]; } /* * Pod Orders */ // Create function createPodOrder( uint256 beanAmount, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount, LibTransfer.From mode ) external payable returns (bytes32 id) { beanAmount = LibTransfer.receiveToken(C.bean(), beanAmount, msg.sender, mode); return _createPodOrder(beanAmount, pricePerPod, maxPlaceInLine, minFillAmount); } function createPodOrderV2( uint256 beanAmount, uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.From mode ) external payable returns (bytes32 id) { beanAmount = LibTransfer.receiveToken(C.bean(), beanAmount, msg.sender, mode); return _createPodOrderV2(beanAmount, maxPlaceInLine, minFillAmount, pricingFunction); } // Fill function fillPodOrder( PodOrder calldata o, uint256 index, uint256 start, uint256 amount, LibTransfer.To mode ) external payable { _fillPodOrder(o, index, start, amount, mode); } function fillPodOrderV2( PodOrder calldata o, uint256 index, uint256 start, uint256 amount, bytes calldata pricingFunction, LibTransfer.To mode ) external payable { _fillPodOrderV2(o, index, start, amount, pricingFunction, mode); } // Cancel function cancelPodOrder( uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount, LibTransfer.To mode ) external payable { _cancelPodOrder(pricePerPod, maxPlaceInLine, minFillAmount, mode); } function cancelPodOrderV2( uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.To mode ) external payable { _cancelPodOrderV2(maxPlaceInLine, minFillAmount, pricingFunction, mode); } // Get function podOrder( address account, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount ) external view returns (uint256) { return s.podOrders[ createOrderId( account, pricePerPod, maxPlaceInLine, minFillAmount ) ]; } function podOrderV2( address account, uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction ) external view returns (uint256) { return s.podOrders[ createOrderIdV2( account, 0, maxPlaceInLine, minFillAmount, pricingFunction ) ]; } function podOrderById(bytes32 id) external view returns (uint256) { return s.podOrders[id]; } /* * Transfer Plot */ function transferPlot( address sender, address recipient, uint256 id, uint256 start, uint256 end ) external payable nonReentrant { require( sender != address(0) && recipient != address(0), "Field: Transfer to/from 0 address." ); uint256 amount = s.a[sender].field.plots[id]; require(amount > 0, "Field: Plot not owned by user."); require(end > start && amount >= end, "Field: Pod range invalid."); amount = end - start; // Note: SafeMath is redundant here. if (msg.sender != sender && allowancePods(sender, msg.sender) != uint256(-1)) { decrementAllowancePods(sender, msg.sender, amount); } if (s.podListings[id] != bytes32(0)){ _cancelPodListing(sender, id); } _transferPlot(sender, recipient, id, start, amount); } function approvePods(address spender, uint256 amount) external payable nonReentrant { require(spender != address(0), "Field: Pod Approve to 0 address."); setAllowancePods(msg.sender, spender, amount); emit PodApproval(msg.sender, spender, amount); } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "./Listing.sol"; /** * @author Beanjoyer, Malteasy * @title Pod Marketplace v2 **/ contract Order is Listing { using SafeMath for uint256; struct PodOrder { address account; uint24 pricePerPod; uint256 maxPlaceInLine; uint256 minFillAmount; } event PodOrderCreated( address indexed account, bytes32 id, uint256 amount, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount, bytes pricingFunction, LibPolynomial.PriceType priceType ); event PodOrderFilled( address indexed from, address indexed to, bytes32 id, uint256 index, uint256 start, uint256 amount, uint256 costInBeans ); event PodOrderCancelled(address indexed account, bytes32 id); /* * Create */ // Note: Orders changed and now can accept an arbitary amount of beans, possibly higher than the value of the order /* Note: Fixed pod orders store at s.podOrders[id] the amount of pods that they order * whereas dynamic orders store the amount of beans used to make the order */ function _createPodOrder( uint256 beanAmount, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount ) internal returns (bytes32 id) { require(beanAmount > 0, "Marketplace: Order amount must be > 0."); require(pricePerPod > 0, "Marketplace: Pod price must be greater than 0."); id = createOrderId(msg.sender, pricePerPod, maxPlaceInLine, minFillAmount); if (s.podOrders[id] > 0) _cancelPodOrder(pricePerPod, maxPlaceInLine, minFillAmount, LibTransfer.To.INTERNAL); s.podOrders[id] = beanAmount; bytes memory emptyPricingFunction; emit PodOrderCreated(msg.sender, id, beanAmount, pricePerPod, maxPlaceInLine, minFillAmount, emptyPricingFunction, LibPolynomial.PriceType.Fixed); } function _createPodOrderV2( uint256 beanAmount, uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction ) internal returns (bytes32 id) { require(beanAmount > 0, "Marketplace: Order amount must be > 0."); id = createOrderIdV2(msg.sender, 0, maxPlaceInLine, minFillAmount, pricingFunction); if (s.podOrders[id] > 0) _cancelPodOrderV2(maxPlaceInLine, minFillAmount, pricingFunction, LibTransfer.To.INTERNAL); s.podOrders[id] = beanAmount; emit PodOrderCreated(msg.sender, id, beanAmount, 0, maxPlaceInLine, minFillAmount, pricingFunction, LibPolynomial.PriceType.Dynamic); } /* * Fill */ function _fillPodOrder( PodOrder calldata o, uint256 index, uint256 start, uint256 amount, LibTransfer.To mode ) internal { require(amount >= o.minFillAmount, "Marketplace: Fill must be >= minimum amount."); require(s.a[msg.sender].field.plots[index] >= (start.add(amount)), "Marketplace: Invalid Plot."); require(index.add(start).add(amount).sub(s.f.harvestable) <= o.maxPlaceInLine, "Marketplace: Plot too far in line."); bytes32 id = createOrderId(o.account, o.pricePerPod, o.maxPlaceInLine, o.minFillAmount); uint256 costInBeans = amount.mul(o.pricePerPod).div(1000000); s.podOrders[id] = s.podOrders[id].sub(costInBeans, "Marketplace: Not enough beans in order."); LibTransfer.sendToken(C.bean(), costInBeans, msg.sender, mode); if (s.podListings[index] != bytes32(0)) _cancelPodListing(msg.sender, index); _transferPlot(msg.sender, o.account, index, start, amount); if (s.podOrders[id] == 0) delete s.podOrders[id]; emit PodOrderFilled(msg.sender, o.account, id, index, start, amount, costInBeans); } function _fillPodOrderV2( PodOrder calldata o, uint256 index, uint256 start, uint256 amount, bytes calldata pricingFunction, LibTransfer.To mode ) internal { require(amount >= o.minFillAmount, "Marketplace: Fill must be >= minimum amount."); require(s.a[msg.sender].field.plots[index] >= (start.add(amount)), "Marketplace: Invalid Plot."); require(index.add(start).add(amount).sub(s.f.harvestable) <= o.maxPlaceInLine, "Marketplace: Plot too far in line."); bytes32 id = createOrderIdV2(o.account, 0, o.maxPlaceInLine, o.minFillAmount, pricingFunction); uint256 costInBeans = getAmountBeansToFillOrderV2(index.add(start).sub(s.f.harvestable), amount, pricingFunction); s.podOrders[id] = s.podOrders[id].sub(costInBeans, "Marketplace: Not enough beans in order."); LibTransfer.sendToken(C.bean(), costInBeans, msg.sender, mode); if (s.podListings[index] != bytes32(0)) _cancelPodListing(msg.sender, index); _transferPlot(msg.sender, o.account, index, start, amount); if (s.podOrders[id] == 0) delete s.podOrders[id]; emit PodOrderFilled(msg.sender, o.account, id, index, start, amount, costInBeans); } /* * Cancel */ function _cancelPodOrder( uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount, LibTransfer.To mode ) internal { bytes32 id = createOrderId(msg.sender, pricePerPod, maxPlaceInLine, minFillAmount); uint256 amountBeans = s.podOrders[id]; LibTransfer.sendToken(C.bean(), amountBeans, msg.sender, mode); delete s.podOrders[id]; emit PodOrderCancelled(msg.sender, id); } function _cancelPodOrderV2( uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.To mode ) internal { bytes32 id = createOrderIdV2(msg.sender, 0, maxPlaceInLine, minFillAmount, pricingFunction); uint256 amountBeans = s.podOrders[id]; LibTransfer.sendToken(C.bean(), amountBeans, msg.sender, mode); delete s.podOrders[id]; emit PodOrderCancelled(msg.sender, id); } /* * PRICING */ /** Consider a piecewise with the following breakpoints: [b0, b1, b2, b3, b4] Let us say the start of our integration falls in the range [b0, b1], and the end of our integration falls in the range [b3, b4]. Then our integration splits into: I(start, b1) + I(b1, b2) + I(b2, b3) + I(b3, end). */ /** * @notice Calculates the amount of beans needed to fill an order. * @dev Integration over a range that falls within piecewise domain. */ function getAmountBeansToFillOrderV2( uint256 placeInLine, uint256 amountPodsFromOrder, bytes calldata pricingFunction ) public pure returns (uint256 beanAmount) { beanAmount = LibPolynomial.evaluatePolynomialIntegrationPiecewise(pricingFunction, placeInLine, placeInLine.add(amountPodsFromOrder)); beanAmount = beanAmount.div(1000000); } /* * Helpers */ function createOrderId( address account, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount ) internal pure returns (bytes32 id) { if(minFillAmount > 0) id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine, minFillAmount)); else id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine)); } function createOrderIdV2( address account, uint24 pricePerPod, uint256 maxPlaceInLine, uint256 minFillAmount, bytes calldata pricingFunction ) internal pure returns (bytes32 id) { require(pricingFunction.length == LibPolynomial.getNumPieces(pricingFunction).mul(168).add(32), "Marketplace: Invalid pricing function."); id = keccak256(abi.encodePacked(account, pricePerPod, maxPlaceInLine, minFillAmount, pricingFunction)); } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "./PodTransfer.sol"; import "../../../libraries/Token/LibTransfer.sol"; import "../../../libraries/LibPolynomial.sol"; /** * @author Beanjoyer, Malteasy * @title Pod Marketplace v2 **/ contract Listing is PodTransfer { using SafeMath for uint256; struct PodListing { address account; uint256 index; uint256 start; uint256 amount; uint24 pricePerPod; uint256 maxHarvestableIndex; uint256 minFillAmount; LibTransfer.To mode; } event PodListingCreated( address indexed account, uint256 index, uint256 start, uint256 amount, uint24 pricePerPod, uint256 maxHarvestableIndex, uint256 minFillAmount, bytes pricingFunction, LibTransfer.To mode, LibPolynomial.PriceType pricingType ); event PodListingFilled( address indexed from, address indexed to, uint256 index, uint256 start, uint256 amount, uint256 costInBeans ); event PodListingCancelled(address indexed account, uint256 index); /* * Create */ function _createPodListing( uint256 index, uint256 start, uint256 amount, uint24 pricePerPod, uint256 maxHarvestableIndex, uint256 minFillAmount, LibTransfer.To mode ) internal { uint256 plotSize = s.a[msg.sender].field.plots[index]; require(plotSize >= (start.add(amount)) && amount > 0, "Marketplace: Invalid Plot/Amount."); require(pricePerPod > 0, "Marketplace: Pod price must be greater than 0."); require(s.f.harvestable <= maxHarvestableIndex, "Marketplace: Expired."); if (s.podListings[index] != bytes32(0)) _cancelPodListing(msg.sender, index); s.podListings[index] = hashListing(start, amount, pricePerPod, maxHarvestableIndex, minFillAmount, mode); bytes memory f; emit PodListingCreated(msg.sender, index, start, amount, pricePerPod, maxHarvestableIndex, minFillAmount, f, mode, LibPolynomial.PriceType.Fixed); } function _createPodListingV2( uint256 index, uint256 start, uint256 amount, uint256 maxHarvestableIndex, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.To mode ) internal { uint256 plotSize = s.a[msg.sender].field.plots[index]; require(plotSize >= (start.add(amount)) && amount > 0, "Marketplace: Invalid Plot/Amount."); require(s.f.harvestable <= maxHarvestableIndex, "Marketplace: Expired."); if (s.podListings[index] != bytes32(0)) _cancelPodListing(msg.sender, index); s.podListings[index] = hashListingV2( start, amount, 0, maxHarvestableIndex, minFillAmount, pricingFunction, mode ); emit PodListingCreated( msg.sender, index, start, amount, 0, maxHarvestableIndex, minFillAmount, pricingFunction, mode, LibPolynomial.PriceType.Dynamic ); } /* * Fill */ function _fillListing(PodListing calldata l, uint256 beanAmount) internal { bytes32 lHash = hashListing( l.start, l.amount, l.pricePerPod, l.maxHarvestableIndex, l.minFillAmount, l.mode ); require(s.podListings[l.index] == lHash, "Marketplace: Listing does not exist."); uint256 plotSize = s.a[l.account].field.plots[l.index]; require(plotSize >= (l.start.add(l.amount)) && l.amount > 0, "Marketplace: Invalid Plot/Amount."); require(s.f.harvestable <= l.maxHarvestableIndex, "Marketplace: Listing has expired."); uint256 amount = getAmountPodsFromFillListing(l.pricePerPod, l.amount, beanAmount); __fillListing(msg.sender, l, amount, beanAmount); _transferPlot(l.account, msg.sender, l.index, l.start, amount); } function _fillListingV2( PodListing calldata l, uint256 beanAmount, bytes calldata pricingFunction ) internal { bytes32 lHash = hashListingV2( l.start, l.amount, l.pricePerPod, l.maxHarvestableIndex, l.minFillAmount, pricingFunction, l.mode ); require(s.podListings[l.index] == lHash, "Marketplace: Listing does not exist."); uint256 plotSize = s.a[l.account].field.plots[l.index]; require(plotSize >= (l.start.add(l.amount)) && l.amount > 0, "Marketplace: Invalid Plot/Amount."); require(s.f.harvestable <= l.maxHarvestableIndex, "Marketplace: Listing has expired."); uint256 amount = getAmountPodsFromFillListingV2(l.index.add(l.start).sub(s.f.harvestable), l.amount, beanAmount, pricingFunction); __fillListingV2(msg.sender, l, pricingFunction, amount, beanAmount); _transferPlot(l.account, msg.sender, l.index, l.start, amount); } function __fillListing( address to, PodListing calldata l, uint256 amount, uint256 beanAmount ) private { require(amount >= l.minFillAmount, "Marketplace: Fill must be >= minimum amount."); require(l.amount >= amount, "Marketplace: Not enough pods in Listing."); delete s.podListings[l.index]; if (l.amount > amount) { s.podListings[l.index.add(amount).add(l.start)] = hashListing( 0, l.amount.sub(amount), l.pricePerPod, l.maxHarvestableIndex, l.minFillAmount, l.mode ); } emit PodListingFilled(l.account, to, l.index, l.start, amount, beanAmount); } function __fillListingV2( address to, PodListing calldata l, bytes calldata pricingFunction, uint256 amount, uint256 beanAmount ) private { require(amount >= l.minFillAmount, "Marketplace: Fill must be >= minimum amount."); require(l.amount >= amount, "Marketplace: Not enough pods in Listing."); delete s.podListings[l.index]; if (l.amount > amount) { s.podListings[l.index.add(amount).add(l.start)] = hashListingV2( 0, l.amount.sub(amount), l.pricePerPod, l.maxHarvestableIndex, l.minFillAmount, pricingFunction, l.mode ); } emit PodListingFilled(l.account, to, l.index, l.start, amount, beanAmount); } /* * Cancel */ function _cancelPodListing(address account, uint256 index) internal { require( s.a[account].field.plots[index] > 0, "Marketplace: Listing not owned by sender." ); delete s.podListings[index]; emit PodListingCancelled(account, index); } /* * Helpers */ function getAmountPodsFromFillListing(uint24 pricePerPod, uint256 podListingAmount, uint256 fillBeanAmount) internal pure returns (uint256 amount) { amount = (fillBeanAmount * 1000000) / pricePerPod; uint256 remainingAmount = podListingAmount.sub(amount, "Marketplace: Not enough pods in Listing."); if(remainingAmount <= (1000000 / pricePerPod)) amount = podListingAmount; } function getAmountPodsFromFillListingV2( uint256 placeInLine, uint256 podListingAmount, uint256 fillBeanAmount, bytes calldata pricingFunction ) public pure returns (uint256 amount) { uint256 pricePerPod = LibPolynomial.evaluatePolynomialPiecewise(pricingFunction, placeInLine); amount = (fillBeanAmount.mul(1000000)) / pricePerPod; uint256 remainingAmount = podListingAmount.sub(amount, "Marketplace: Not enough pods in Listing."); if(remainingAmount <= (1000000 / pricePerPod)) amount = podListingAmount; } function hashListing( uint256 start, uint256 amount, uint24 pricePerPod, uint256 maxHarvestableIndex, uint256 minFillAmount, LibTransfer.To mode ) internal pure returns (bytes32 lHash) { if(minFillAmount > 0) lHash = keccak256(abi.encodePacked(start, amount, pricePerPod, maxHarvestableIndex, minFillAmount, mode == LibTransfer.To.EXTERNAL)); else lHash = keccak256(abi.encodePacked(start, amount, pricePerPod, maxHarvestableIndex, mode == LibTransfer.To.EXTERNAL)); } function hashListingV2( uint256 start, uint256 amount, uint24 pricePerPod, uint256 maxHarvestableIndex, uint256 minFillAmount, bytes calldata pricingFunction, LibTransfer.To mode ) internal pure returns (bytes32 lHash) { require(pricingFunction.length == LibPolynomial.getNumPieces(pricingFunction).mul(168).add(32), "Marketplace: Invalid pricing function."); lHash = keccak256(abi.encodePacked(start, amount, pricePerPod, maxHarvestableIndex, minFillAmount, mode == LibTransfer.To.EXTERNAL, pricingFunction)); } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import "./LibBytes.sol"; /* * @author: Malteasy * @title: LibPolynomial */ library LibPolynomial { using SafeMath for uint256; using LibBytes for bytes; /** The polynomial's constant terms are split into: 1) constant * 10^exponent , 2) the exponent the constant is raised to in base 10 and, 3) the sign of the coefficients. Example conversion to Piecewise: Range(0, 1) -> Polynomial(0.25*x^3 + 25*x^2 + x + 1) Range(1, 2) -> Polynomial(0.0125*x^3 + 50*x^2 + x - 2) Range(2, Infinity) -> Polynomial(-1) Resulting Piecewise: breakpoints: [0, 1, 2] significands: [1, 1, 25, 25, 2, 1, 50, 125, 1, 0, 0, 0] (expanded) coefficient exponents: [0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0] (expanded) signs: [true, true, true, true, false, true, true, true, false, false, false, false] The resulting piecewise is then encoded into a single bytes array by concatenating as follows, where n is the number of polynomial pieces: [ n, (32 bytes) breakpoints, (32n bytes) significands, (128n bytes) exponents, (4n bytes) signs, (4n bytes) ] */ enum PriceType { Fixed, Dynamic } uint256 constant MAX_DEGREE = 3; /** * @notice Computes a cubic polynomial. * @dev Polynomial is of the form a(x-k)^3 + b(x-k)^2 + c(x-k) + d where k is the start of the piecewise interval * @param f The encoded piecewise polynomial * @param pieceIndex Which piece of the polynomial to evaluate * @param numPieces The number of pieces in the polynomial * @param x The value to be evaluated at. */ function evaluatePolynomial( bytes calldata f, uint256 pieceIndex, uint256 numPieces, uint256 x ) internal pure returns (uint256) { uint256 positiveSum; uint256 negativeSum; uint256[4] memory significands = getSignificands(f, pieceIndex, numPieces); uint8[4] memory exponents = getExponents(f, pieceIndex, numPieces); bool[4] memory signs = getSigns(f, pieceIndex, numPieces); for(uint256 degree; degree <= MAX_DEGREE; ++degree) { if(signs[degree]) { positiveSum = positiveSum.add(pow(x, degree).mul(significands[degree]).div(pow(10, exponents[degree]))); } else { negativeSum = negativeSum.add(pow(x, degree).mul(significands[degree]).div(pow(10, exponents[degree]))); } } return positiveSum.sub(negativeSum); } function evaluatePolynomialPiecewise( bytes calldata f, uint256 x ) internal pure returns (uint256 y) { uint256 numPieces = getNumPieces(f); uint256 pieceIndex = findPiecewiseIndex(f, x, numPieces); y = evaluatePolynomial(f, pieceIndex, numPieces, x.sub(getPiecewiseBreakpoint(f, pieceIndex), "Evaluation must be within piecewise bounds") ); } /** * @notice Computes the integral of a cubic polynomial * @dev Polynomial is of the form a(x-k)^3 + b(x-k)^2 + c(x-k) + d where k is the start of the piecewise interval * @param f The encoded piecewise polynomial * @param pieceIndex Which piece of the polynomial to evaluate * @param numPieces The number of pieces in the polynomial * @param start The lower bound of the integration. (can overflow past 10e13) * @param end The upper bound of the integration. (can overflow past 10e13) */ function evaluatePolynomialIntegration( bytes calldata f, uint256 pieceIndex, uint256 numPieces, uint256 start, //start of breakpoint is assumed to be subtracted uint256 end //start of breakpoint is assumed to be subtracted ) internal pure returns (uint256) { uint256 positiveSum; uint256 negativeSum; uint256[4] memory significands = getSignificands(f, pieceIndex, numPieces); uint8[4] memory exponents = getExponents(f, pieceIndex, numPieces); bool[4] memory signs = getSigns(f, pieceIndex, numPieces); for(uint256 degree; degree <= MAX_DEGREE; ++degree) { if(signs[degree]) { //uint256 max value is 1e77 and this has been tested to work to not overflow for values less than 1e14. //Note: susceptible to overflows past 1e14 positiveSum = positiveSum.add(pow(end, 1 + degree).mul(significands[degree]).div(pow(10, exponents[degree]).mul(1 + degree))); positiveSum = positiveSum.sub(pow(start, 1 + degree).mul(significands[degree]).div(pow(10, exponents[degree]).mul(1 + degree))); } else { negativeSum = negativeSum.add(pow(end, 1 + degree).mul(significands[degree]).div(pow(10, exponents[degree]).mul(1 + degree))); negativeSum = negativeSum.sub(pow(start, 1 + degree).mul(significands[degree]).div(pow(10, exponents[degree]).mul(1 + degree))); } } return positiveSum.sub(negativeSum); } function evaluatePolynomialIntegrationPiecewise( bytes calldata f, uint256 start, uint256 end ) internal pure returns (uint256 integral) { uint256 numPieces = getNumPieces(f); uint256 currentPieceIndex = findPiecewiseIndex(f, start, numPieces); uint256 currentPieceStart = getPiecewiseBreakpoint(f, currentPieceIndex); uint256 nextPieceStart = getPiecewiseBreakpoint(f, currentPieceIndex + 1); bool integrateToEnd; while (!integrateToEnd) { if(end > nextPieceStart) { integrateToEnd = false; } else { integrateToEnd = true; } uint256 startIntegration = start.sub(currentPieceStart, "Evaluation must be within piecewise bounds."); uint256 endIntegration = integrateToEnd ? end.sub(currentPieceStart) : nextPieceStart.sub(currentPieceStart); integral = integral.add(evaluatePolynomialIntegration(f, currentPieceIndex, numPieces, startIntegration, endIntegration )); if(!integrateToEnd) { start = nextPieceStart; if(currentPieceIndex == (numPieces - 1)) { //reached end of piecewise integrateToEnd = true; } else { //continue to next piece currentPieceIndex++; currentPieceStart = getPiecewiseBreakpoint(f, currentPieceIndex); if(currentPieceIndex != (numPieces - 1)) nextPieceStart = getPiecewiseBreakpoint(f, currentPieceIndex + 1); } } } } /** * @notice Searches for index of interval containing x * @dev [inclusiveStart, exclusiveEnd) * @param value The value to search for. * @param high The highest index of the array to search. Could be retrieved from getNumPieces(arr) - 1. */ function findPiecewiseIndex(bytes calldata f, uint256 value, uint256 high) internal pure returns (uint256) { uint256 breakpointAtIndex = getPiecewiseBreakpoint(f, 0); if(value < breakpointAtIndex) return 0; uint256 low = 0; while(low < high) { if(breakpointAtIndex == value) return low; else if(breakpointAtIndex > value) return low - 1; else low++; breakpointAtIndex = getPiecewiseBreakpoint(f, low); } return low - 1; } /** Function calldata parsing. */ /** * @notice Retrieves the length of pieces in a piecewise polynomial. * @dev Stored as the first 32 bytes of the piecewise function data. * @param f The function data of the piecewise polynomial. */ function getNumPieces(bytes calldata f) internal pure returns (uint256) { return f.sliceToMemory(0, 32).toUint256(0); } /** * @notice Retrieves the breakpoint at the specified piecewise index. * @dev Stored in function data after the first 32 bytes. Occupies 32n bytes, where n is the number of polynomial pieces. * @param f The function data of the piecewise polynomial. */ function getPiecewiseBreakpoint(bytes calldata f, uint256 pieceIndex) internal pure returns (uint256) { return f.sliceToMemory((pieceIndex.mul(32)).add(32), 32).toUint256(0); } /** * @notice Retrieves the coefficient significands of a cubic polynomial at specified piecewise index. (significands / 10^exponent = coefficientValue) * @dev Stored in function data after the first 32 + 32n bytes. Occupies 128n bytes, where n is the number of polynomial pieces. * @param f The function data of the piecewise polynomial. * @param pieceIndex The index of the piecewise polynomial to get signs for. * @param numPieces The number of pieces in the piecewise polynomial. */ function getSignificands(bytes calldata f, uint256 pieceIndex, uint256 numPieces) internal pure returns (uint256[4] memory significands) { bytes memory significandSlice = f.sliceToMemory((pieceIndex.mul(128)).add(numPieces.mul(32)).add(32), 128); significands[0] = significandSlice.toUint256(0); significands[1] = significandSlice.toUint256(32); significands[2] = significandSlice.toUint256(64); significands[3] = significandSlice.toUint256(96); } /** * @notice Retrieves the exponents for the coefficients of a cubic polynomial at specified piecewise index. (significand / 10^exponent = coefficientValue) * @dev Stored in function data after the first 32 + 32n + 128n bytes. Occupies 4n bytes, where n is the number of polynomial pieces. * @param f The function data of the piecewise polynomial. * @param pieceIndex The index of the piecewise polynomial to get signs for. * @param numPieces The number of pieces in the piecewise polynomial. */ function getExponents(bytes calldata f, uint256 pieceIndex, uint256 numPieces) internal pure returns(uint8[4] memory exponents) { bytes memory exponentSlice = f.sliceToMemory((pieceIndex.mul(4)).add(numPieces.mul(160)).add(32), 4); exponents[0] = exponentSlice.toUint8(0); exponents[1] = exponentSlice.toUint8(1); exponents[2] = exponentSlice.toUint8(2); exponents[3] = exponentSlice.toUint8(3); } /** * @notice Retrieves the signs (bool values) for the coefficients of a cubic polynomial at specified piecewise index. * @dev Stored in function data after the first 32 + 32n + 128n + 4n bytes. Occupies 4n bytes, where n is the number of polynomial pieces. * @param f The function data of the piecewise polynomial. * @param pieceIndex The index of the piecewise polynomial to get signs for. * @param numPieces The number of pieces in the piecewise polynomial. */ function getSigns(bytes calldata f, uint256 pieceIndex, uint256 numPieces) internal pure returns(bool[4] memory signs) { bytes memory signSlice = f.sliceToMemory((pieceIndex.mul(4)).add(numPieces.mul(164)).add(32), 4); signs[0] = signSlice.toUint8(0) == 1; signs[1] = signSlice.toUint8(1) == 1; signs[2] = signSlice.toUint8(2) == 1; signs[3] = signSlice.toUint8(3) == 1; } /** * @notice A safe way to take the power of a number. */ function pow(uint256 base, uint256 exponent) internal pure returns (uint256) { if(exponent == 0) return 1; else if(exponent == 1) return base; else if(base == 0 && exponent != 0) return 0; else { uint256 z = base; for(uint256 i = 1; i < exponent; ++i) z = z.mul(base); return z; } } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/math/SafeMath.sol"; import "../../AppStorage.sol"; import "../../../interfaces/IBean.sol"; import "../../../libraries/LibSafeMath32.sol"; import "../../ReentrancyGuard.sol"; import "../../../C.sol"; /** * @author Publius * @title Pod Transfer **/ contract PodTransfer is ReentrancyGuard { using SafeMath for uint256; using LibSafeMath32 for uint32; event PlotTransfer( address indexed from, address indexed to, uint256 indexed id, uint256 pods ); event PodApproval( address indexed owner, address indexed spender, uint256 pods ); /** * Getters **/ function allowancePods(address owner, address spender) public view returns (uint256) { return s.a[owner].field.podAllowances[spender]; } /** * Internal **/ function _transferPlot( address from, address to, uint256 index, uint256 start, uint256 amount ) internal { require(from != to, "Field: Cannot transfer Pods to oneself."); insertPlot(to, index.add(start), amount); removePlot(from, index, start, amount.add(start)); emit PlotTransfer(from, to, index.add(start), amount); } function insertPlot( address account, uint256 id, uint256 amount ) internal { s.a[account].field.plots[id] = amount; } function removePlot( address account, uint256 id, uint256 start, uint256 end ) internal { uint256 amount = s.a[account].field.plots[id]; if (start == 0) delete s.a[account].field.plots[id]; else s.a[account].field.plots[id] = start; if (end != amount) s.a[account].field.plots[id.add(end)] = amount.sub(end); } function decrementAllowancePods( address owner, address spender, uint256 amount ) internal { uint256 currentAllowance = allowancePods(owner, spender); setAllowancePods( owner, spender, currentAllowance.sub(amount, "Field: Insufficient approval.") ); } function setAllowancePods( address owner, address spender, uint256 amount ) internal { s.a[owner].field.podAllowances[spender] = amount; } }
/* SPDX-License-Identifier: MIT */ /** * @author publius * @title LibTransfer handles the recieving and sending of Tokens to/from internal Balances. **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "../../interfaces/IBean.sol"; import "./LibBalance.sol"; library LibTransfer { using SafeERC20 for IERC20; using SafeMath for uint256; enum From { EXTERNAL, INTERNAL, EXTERNAL_INTERNAL, INTERNAL_TOLERANT } enum To { EXTERNAL, INTERNAL } function transferToken( IERC20 token, address sender, address recipient, uint256 amount, From fromMode, To toMode ) internal returns (uint256 transferredAmount) { if (fromMode == From.EXTERNAL && toMode == To.EXTERNAL) { uint256 beforeBalance = token.balanceOf(recipient); token.safeTransferFrom(sender, recipient, amount); return token.balanceOf(recipient).sub(beforeBalance); } amount = receiveToken(token, amount, sender, fromMode); sendToken(token, amount, recipient, toMode); return amount; } function receiveToken( IERC20 token, uint256 amount, address sender, From mode ) internal returns (uint256 receivedAmount) { if (amount == 0) return 0; if (mode != From.EXTERNAL) { receivedAmount = LibBalance.decreaseInternalBalance( sender, token, amount, mode != From.INTERNAL ); if (amount == receivedAmount || mode == From.INTERNAL_TOLERANT) return receivedAmount; } uint256 beforeBalance = token.balanceOf(address(this)); token.safeTransferFrom(sender, address(this), amount - receivedAmount); return receivedAmount.add(token.balanceOf(address(this)).sub(beforeBalance)); } function sendToken( IERC20 token, uint256 amount, address recipient, To mode ) internal { if (amount == 0) return; if (mode == To.INTERNAL) LibBalance.increaseInternalBalance(recipient, token, amount); else token.safeTransfer(recipient, amount); } function burnToken( IBean token, uint256 amount, address sender, From mode ) internal returns (uint256 burnt) { // burnToken only can be called with Unripe Bean, Unripe Bean:3Crv or Bean token, which are all Beanstalk tokens. // Beanstalk's ERC-20 implementation uses OpenZeppelin's ERC20Burnable // which reverts if burnFrom function call cannot burn full amount. if (mode == From.EXTERNAL) { token.burnFrom(sender, amount); burnt = amount; } else { burnt = LibTransfer.receiveToken(token, amount, sender, mode); token.burn(burnt); } } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; /* * @author: Malteasy * @title: LibBytes */ library LibBytes { /* * @notice From Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> */ function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_start + 1 >= _start, "toUint8_overflow"); require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } /* * @notice From Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> */ function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_start + 32 >= _start, "toUint256_overflow"); require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } /** * @notice Loads a slice of a calldata bytes array into memory * @param b The calldata bytes array to load from * @param start The start of the slice * @param length The length of the slice */ function sliceToMemory(bytes calldata b, uint256 start, uint256 length) internal pure returns (bytes memory) { bytes memory memBytes = new bytes(length); for(uint256 i = 0; i < length; ++i) { memBytes[i] = b[start + i]; } return memBytes; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ 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; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
/** * SPDX-License-Identifier: MIT **/ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @author Publius * @title Bean Interface **/ abstract contract IBean is IERC20 { function burn(uint256 amount) public virtual; function burnFrom(address account, uint256 amount) public virtual; function mint(address account, uint256 amount) public virtual; }
/* SPDX-License-Identifier: MIT */ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "../interfaces/IDiamondCut.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; /** * @author Publius * @title App Storage defines the state object for Beanstalk. **/ // The Account contract stores all of the Farmer specific storage data. // Each unique Ethereum address is a Farmer. // Account.State is the primary struct that is referenced in the greater Storage.State struct. // All other structs in Account are stored in Account.State. contract Account { // Field stores a Farmer's Plots and Pod allowances. struct Field { mapping(uint256 => uint256) plots; // A Farmer's Plots. Maps from Plot index to Pod amount. mapping(address => uint256) podAllowances; // An allowance mapping for Pods similar to that of the ERC-20 standard. Maps from spender address to allowance amount. } // Asset Silo is a struct that stores Deposits and Seeds per Deposit, and formerly stored Withdrawals. // Asset Silo currently stores Unripe Bean and Unripe LP Deposits. struct AssetSilo { mapping(uint32 => uint256) withdrawals; // DEPRECATED – Silo V1 Withdrawals are no longer referenced. mapping(uint32 => uint256) deposits; // Unripe Bean/LP Deposits (previously Bean/LP Deposits). mapping(uint32 => uint256) depositSeeds; // BDV of Unripe LP Deposits / 4 (previously # of Seeds in corresponding LP Deposit). } // Deposit represents a Deposit in the Silo of a given Token at a given Season. // Stored as two uint128 state variables to save gas. struct Deposit { uint128 amount; // The amount of Tokens in the Deposit. uint128 bdv; // The Bean-denominated-value of the total amount of Tokens in the Deposit. } // Silo stores Silo-related balances struct Silo { uint256 stalk; // Balance of the Farmer's normal Stalk. uint256 seeds; // Balance of the Farmer's normal Seeds. } // Season Of Plenty stores Season of Plenty (SOP) related balances struct SeasonOfPlenty { // uint256 base; // DEPRECATED – Post Replant SOPs are denominated in plenty Tokens instead of base. uint256 roots; // The number of Roots a Farmer had when it started Raining. // uint256 basePerRoot; // DEPRECATED – Post Replant SOPs are denominated in plenty Tokens instead of base. uint256 plentyPerRoot; // The global Plenty Per Root index at the last time a Farmer updated their Silo. uint256 plenty; // The balance of a Farmer's plenty. Plenty can be claimed directly for 3Crv. } // The Account level State stores all of the Farmer's balances in the contract. // The global AppStorage state stores a mapping from account address to Account.State. struct State { Field field; // A Farmer's Field storage. AssetSilo bean; // A Farmer's Unripe Bean Deposits only as a result of Replant (previously held the V1 Silo Deposits/Withdrawals for Beans). AssetSilo lp; // A Farmer's Unripe LP Deposits as a result of Replant of BEAN:ETH Uniswap v2 LP Tokens (previously held the V1 Silo Deposits/Withdrawals for BEAN:ETH Uniswap v2 LP Tokens). Silo s; // A Farmer's Silo storage. uint32 votedUntil; // DEPRECATED – Replant removed on-chain governance including the ability to vote on BIPs. uint32 lastUpdate; // The Season in which the Farmer last updated their Silo. uint32 lastSop; // The last Season that a SOP occured at the time the Farmer last updated their Silo. uint32 lastRain; // The last Season that it started Raining at the time the Farmer last updated their Silo. uint32 lastSIs; // DEPRECATED – In Silo V1.2, the Silo reward mechanism was updated to no longer need to store the number of the Supply Increases at the time the Farmer last updated their Silo. uint32 proposedUntil; // DEPRECATED – Replant removed on-chain governance including the ability to propose BIPs. SeasonOfPlenty deprecated; // DEPRECATED – Replant reset the Season of Plenty mechanism uint256 roots; // A Farmer's Root balance. uint256 wrappedBeans; // DEPRECATED – Replant generalized Internal Balances. Wrapped Beans are now stored at the AppStorage level. mapping(address => mapping(uint32 => Deposit)) deposits; // A Farmer's Silo Deposits stored as a map from Token address to Season of Deposit to Deposit. mapping(address => mapping(uint32 => uint256)) withdrawals; // A Farmer's Withdrawals from the Silo stored as a map from Token address to Season the Withdrawal becomes Claimable to Withdrawn amount of Tokens. SeasonOfPlenty sop; // A Farmer's Season Of Plenty storage. mapping(address => mapping(address => uint256)) depositAllowances; // Spender => Silo Token mapping(address => mapping(IERC20 => uint256)) tokenAllowances; // Token allowances uint256 depositPermitNonces; // A Farmer's current deposit permit nonce uint256 tokenPermitNonces; // A Farmer's current token permit nonce } } // Storage stores the Global Beanstalk State. // Storage.State stores the highest level State // All Facets define Storage.State as the first and only state variable in the contract. contract Storage { // DEPRECATED – After Replant, Beanstalk stores Token addresses as constants to save gas. // Contracts stored the contract addresses of various important contracts to Beanstalk. struct Contracts { address bean; // DEPRECATED – See above note address pair; // DEPRECATED – See above note address pegPair; // DEPRECATED – See above note address weth; // DEPRECATED – See above note } // Field stores global Field balances. struct Field { uint256 soil; // The number of Soil currently available. uint256 pods; // The pod index; the total number of Pods ever minted. uint256 harvested; // The harvested index; the total number of Pods that have ever been Harvested. uint256 harvestable; // The harvestable index; the total number of Pods that have ever been Harvestable. Included previously Harvested Beans. } // DEPRECATED – Replant moved governance off-chain. // Bip stores Bip related data. struct Bip { address proposer; // DEPRECATED – See above note uint32 start; // DEPRECATED – See above note uint32 period; // DEPRECATED – See above note bool executed; // DEPRECATED – See above note int pauseOrUnpause; // DEPRECATED – See above note uint128 timestamp; // DEPRECATED – See above note uint256 roots; // DEPRECATED – See above note uint256 endTotalRoots; // DEPRECATED – See above note } // DEPRECATED – Replant moved governance off-chain. // DiamondCut stores DiamondCut related data for each Bip. struct DiamondCut { IDiamondCut.FacetCut[] diamondCut; address initAddress; bytes initData; } // DEPRECATED – Replant moved governance off-chain. // Governance stores global Governance balances. struct Governance { uint32[] activeBips; // DEPRECATED – See above note uint32 bipIndex; // DEPRECATED – See above note mapping(uint32 => DiamondCut) diamondCuts; // DEPRECATED – See above note mapping(uint32 => mapping(address => bool)) voted; // DEPRECATED – See above note mapping(uint32 => Bip) bips; // DEPRECATED – See above note } // AssetSilo stores global Token level Silo balances. // In Storage.State there is a mapping from Token address to AssetSilo. struct AssetSilo { uint256 deposited; // The total number of a given Token currently Deposited in the Silo. uint256 withdrawn; // The total number of a given Token currently Withdrawn From the Silo but not Claimed. } // Silo stores global level Silo balances. struct Silo { uint256 stalk; // The total amount of active Stalk (including Earned Stalk, excluding Grown Stalk). uint256 seeds; // The total amount of active Seeds (excluding Earned Seeds). uint256 roots; // Total amount of Roots. } // Oracle stores global level Oracle balances. // Currently the oracle refers to the time weighted average delta b calculated from the Bean:3Crv pool. struct Oracle { bool initialized; // True if the Oracle has been initialzed. It needs to be initialized on Deployment and re-initialized each Unpause. uint32 startSeason; // The Season the Oracle started minting. Used to ramp up delta b when oracle is first added. uint256[2] balances; // The cumulative reserve balances of the pool at the start of the Season (used for computing time weighted average delta b). uint256 timestamp; // The timestamp of the start of the current Season. } // Rain stores global level Rain balances. (Rain is when P > 1, Pod rate Excessively Low). // Note: The `raining` storage variable is stored in the Season section for a gas efficient read operation. struct Rain { uint256 depreciated; // Ocupies a storage slot in place of a deprecated State variable. uint256 pods; // The number of Pods when it last started Raining. uint256 roots; // The number of Roots when it last started Raining. } // Sesaon stores global level Season balances. struct Season { // The first storage slot in Season is filled with a variety of somewhat unrelated storage variables. // Given that they are all smaller numbers, they are stored together for gas efficient read/write operations. // Apologies if this makes it confusing :( uint32 current; // The current Season in Beanstalk. uint32 lastSop; // The Season in which the most recent consecutive series of Seasons of Plenty started. uint8 withdrawSeasons; // The number of seasons required to Withdraw a Deposit. uint32 lastSopSeason; // The Season in which the most recent consecutive series of Seasons of Plenty ended. uint32 rainStart; // rainStart stores the most recent Season in which Rain started. bool raining; // True if it is Raining (P < 1, Pod Rate Excessively Low). bool fertilizing; // True if Beanstalk has Fertilizer left to be paid off. uint256 start; // The timestamp of the Beanstalk deployment rounded down to the nearest hour. uint256 period; // The length of each season in Beanstalk. uint256 timestamp; // The timestamp of the start of the current Season. } // Weather stores global level Weather balances. struct Weather { uint256 startSoil; // The number of Soil at the start of the current Season. uint256 lastDSoil; // Delta Soil; the number of Soil purchased last Season. uint96 lastSoilPercent; // DEPRECATED: Was removed with Extreme Weather V2 uint32 lastSowTime; // The number of seconds it took for all but at most 1 Soil to sell out last Season. uint32 nextSowTime; // The number of seconds it took for all but at most 1 Soil to sell out this Season uint32 yield; // Weather; the interest rate for sowing Beans in Soil. bool didSowBelowMin; // DEPRECATED: Was removed with Extreme Weather V2 bool didSowFaster; // DEPRECATED: Was removed with Extreme Weather V2 } // Fundraiser stores Fundraiser data for a given Fundraiser. struct Fundraiser { address payee; // The address to be paid after the Fundraiser has been fully funded. address token; // The token address that used to raise funds for the Fundraiser. uint256 total; // The total number of Tokens that need to be raised to complete the Fundraiser. uint256 remaining; // The remaining number of Tokens that need to to complete the Fundraiser. uint256 start; // The timestamp at which the Fundraiser started (Fundraisers cannot be started and funded in the same block). } // SiloSettings stores the settings for each Token that has been Whitelisted into the Silo. // A Token is considered whitelisted in the Silo if there exists a non-zero SiloSettings selector. struct SiloSettings { // selector is an encoded function selector // that pertains to an external view Beanstalk function // with the following signature: // function tokenToBdv(uint256 amount) public view returns (uint256); // It is called by `LibTokenSilo` through the use of delegatecall // To calculate the BDV of a Deposit at the time of Deposit. bytes4 selector; // The encoded BDV function selector for the Token. uint32 seeds; // The Seeds Per BDV that the Silo mints in exchange for Depositing this Token. uint32 stalk; // The Stalk Per BDV that the Silo mints in exchange for Depositing this Token. } // UnripeSettings stores the settings for an Unripe Token in Beanstalk. // An Unripe token is a vesting Token that is redeemable for a a pro rata share // of the balanceOfUnderlying subject to a penalty based on the percent of // Unfertilized Beans paid back. // There were two Unripe Tokens added at Replant: // Unripe Bean with its underlying Token as Bean; and // Unripe LP with its underlying Token as Bean:3Crv LP. // Unripe Tokens are distirbuted through the use of a merkleRoot. // The existence of a non-zero UnripeSettings implies that a Token is an Unripe Token. struct UnripeSettings { address underlyingToken; // The address of the Token underlying the Unripe Token. uint256 balanceOfUnderlying; // The number of Tokens underlying the Unripe Tokens (redemption pool). bytes32 merkleRoot; // The Merkle Root used to validate a claim of Unripe Tokens. } } struct AppStorage { uint8 index; // DEPRECATED - Was the index of the Bean token in the Bean:Eth Uniswap v2 pool, which has been depreciated. int8[32] cases; // The 24 Weather cases (array has 32 items, but caseId = 3 (mod 4) are not cases). bool paused; // True if Beanstalk is Paused. uint128 pausedAt; // The timestamp at which Beanstalk was last paused. Storage.Season season; // The Season storage struct found above. Storage.Contracts c; // DEPRECATED - Previously stored the Contracts State struct. Removed when contract addresses were moved to constants in C.sol. Storage.Field f; // The Field storage struct found above. Storage.Governance g; // The Governance storage struct found above. Storage.Oracle co; // The Oracle storage struct found above. Storage.Rain r; // The Rain storage struct found above. Storage.Silo s; // The Silo storage struct found above. uint256 reentrantStatus; // An intra-transaction state variable to protect against reentrance. Storage.Weather w; // The Weather storage struct found above. ////////////////////////////////// uint256 earnedBeans; // The number of Beans distributed to the Silo that have not yet been Deposited as a result of the Earn function being called. uint256[14] depreciated; // DEPRECATED - 14 slots that used to store state variables which have been deprecated through various updates. Storage slots can be left alone or reused. mapping (address => Account.State) a; // A mapping from Farmer address to Account state. uint32 bip0Start; // DEPRECATED - bip0Start was used to aid in a migration that occured alongside BIP-0. uint32 hotFix3Start; // DEPRECATED - hotFix3Start was used to aid in a migration that occured alongside HOTFIX-3. mapping (uint32 => Storage.Fundraiser) fundraisers; // A mapping from Fundraiser Id to Fundraiser storage. uint32 fundraiserIndex; // The number of Fundraisers that have occured. mapping (address => bool) isBudget; // DEPRECATED - Budget Facet was removed in BIP-14. mapping(uint256 => bytes32) podListings; // A mapping from Plot Index to the hash of the Pod Listing. mapping(bytes32 => uint256) podOrders; // A mapping from the hash of a Pod Order to the amount of Pods that the Pod Order is still willing to buy. mapping(address => Storage.AssetSilo) siloBalances; // A mapping from Token address to Silo Balance storage (amount deposited and withdrawn). mapping(address => Storage.SiloSettings) ss; // A mapping from Token address to Silo Settings for each Whitelisted Token. If a non-zero storage exists, a Token is whitelisted. uint256[3] depreciated2; // DEPRECATED - 3 slots that used to store state variables which have been depreciated through various updates. Storage slots can be left alone or reused. // New Sops mapping (uint32 => uint256) sops; // A mapping from Season to Plenty Per Root (PPR) in that Season. Plenty Per Root is 0 if a Season of Plenty did not occur. // Internal Balances mapping(address => mapping(IERC20 => uint256)) internalTokenBalance; // A mapping from Farmer address to Token address to Internal Balance. It stores the amount of the Token that the Farmer has stored as an Internal Balance in Beanstalk. // Unripe mapping(address => mapping(address => bool)) unripeClaimed; // True if a Farmer has Claimed an Unripe Token. A mapping from Farmer to Unripe Token to its Claim status. mapping(address => Storage.UnripeSettings) u; // Unripe Settings for a given Token address. The existence of a non-zero Unripe Settings implies that the token is an Unripe Token. The mapping is from Token address to Unripe Settings. // Fertilizer mapping(uint128 => uint256) fertilizer; // A mapping from Fertilizer Id to the supply of Fertilizer for each Id. mapping(uint128 => uint128) nextFid; // A linked list of Fertilizer Ids ordered by Id number. Fertilizer Id is the Beans Per Fertilzer level at which the Fertilizer no longer receives Beans. Sort in order by which Fertilizer Id expires next. uint256 activeFertilizer; // The number of active Fertilizer. uint256 fertilizedIndex; // The total number of Fertilizer Beans. uint256 unfertilizedIndex; // The total number of Unfertilized Beans ever. uint128 fFirst; // The lowest active Fertilizer Id (start of linked list that is stored by nextFid). uint128 fLast; // The highest active Fertilizer Id (end of linked list that is stored by nextFid). uint128 bpf; // The cumulative Beans Per Fertilizer (bfp) minted over all Season. uint256 recapitalized; // The nubmer of USDC that has been recapitalized in the Barn Raise. uint256 isFarm; // Stores whether the function is wrapped in the `farm` function (1 if not, 2 if it is). address ownerCandidate; // Stores a candidate address to transfer ownership to. The owner must claim the ownership transfer. }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @author Publius * @title LibSafeMath32 is a uint32 variation of Open Zeppelin's Safe Math library. **/ library LibSafeMath32 { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint32 a, uint32 b) internal pure returns (bool, uint32) { uint32 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint32 a, uint32 b) internal pure returns (bool, uint32) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint32 a, uint32 b) internal pure returns (bool, uint32) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint32 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint32 a, uint32 b) internal pure returns (bool, uint32) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint32 a, uint32 b) internal pure returns (bool, uint32) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint32 a, uint32 b) internal pure returns (uint32) { uint32 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint32 a, uint32 b) internal pure returns (uint32) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint32 a, uint32 b) internal pure returns (uint32) { if (a == 0) return 0; uint32 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint32 a, uint32 b) internal pure returns (uint32) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint32 a, uint32 b) internal pure returns (uint32) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint32 a, uint32 b, string memory errorMessage) internal pure returns (uint32) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "./AppStorage.sol"; /** * @author Beanstalk Farms * @title Variation of Oepn Zeppelins reentrant guard to include Silo Update * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts%2Fsecurity%2FReentrancyGuard.sol **/ abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; AppStorage internal s; modifier nonReentrant() { require(s.reentrantStatus != _ENTERED, "ReentrancyGuard: reentrant call"); s.reentrantStatus = _ENTERED; _; s.reentrantStatus = _NOT_ENTERED; } }
/* SPDX-License-Identifier: MIT */ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "./interfaces/IBean.sol"; import "./interfaces/ICurve.sol"; import "./interfaces/IFertilizer.sol"; import "./interfaces/IProxyAdmin.sol"; import "./libraries/Decimal.sol"; /** * @author Publius * @title C holds the contracts for Beanstalk. **/ library C { using Decimal for Decimal.D256; using SafeMath for uint256; // Constants uint256 private constant PERCENT_BASE = 1e18; uint256 private constant PRECISION = 1e18; // Chain uint256 private constant CHAIN_ID = 1; // Mainnet // Season uint256 private constant CURRENT_SEASON_PERIOD = 3600; // 1 hour uint256 private constant BASE_ADVANCE_INCENTIVE = 100e6; // 100 beans uint256 private constant SOP_PRECISION = 1e24; // Sun uint256 private constant FERTILIZER_DENOMINATOR = 3; uint256 private constant HARVEST_DENOMINATOR = 2; uint256 private constant SOIL_COEFFICIENT_HIGH = 0.5e18; uint256 private constant SOIL_COEFFICIENT_LOW = 1.5e18; // Weather uint256 private constant POD_RATE_LOWER_BOUND = 0.05e18; // 5% uint256 private constant OPTIMAL_POD_RATE = 0.15e18; // 15% uint256 private constant POD_RATE_UPPER_BOUND = 0.25e18; // 25% uint32 private constant STEADY_SOW_TIME = 60; // 1 minute uint256 private constant DELTA_POD_DEMAND_LOWER_BOUND = 0.95e18; // 95% uint256 private constant DELTA_POD_DEMAND_UPPER_BOUND = 1.05e18; // 105% // Silo uint256 private constant SEEDS_PER_BEAN = 2; uint256 private constant STALK_PER_BEAN = 10000; uint256 private constant ROOTS_BASE = 1e12; // Exploit uint256 private constant UNRIPE_LP_PER_DOLLAR = 1884592; // 145_113_507_403_282 / 77_000_000 uint256 private constant ADD_LP_RATIO = 866616; uint256 private constant INITIAL_HAIRCUT = 185564685220298701; // SET // Contracts address private constant BEAN = 0xBEA0000029AD1c77D3d5D23Ba2D8893dB9d1Efab; address private constant CURVE_BEAN_METAPOOL = 0xc9C32cd16Bf7eFB85Ff14e0c8603cc90F6F2eE49; address private constant CURVE_3_POOL = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7; address private constant THREE_CRV = 0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490; address private constant UNRIPE_BEAN = 0x1BEA0050E63e05FBb5D8BA2f10cf5800B6224449; address private constant UNRIPE_LP = 0x1BEA3CcD22F4EBd3d37d731BA31Eeca95713716D; address private constant FERTILIZER = 0x402c84De2Ce49aF88f5e2eF3710ff89bFED36cB6; address private constant FERTILIZER_ADMIN = 0xfECB01359263C12Aa9eD838F878A596F0064aa6e; address private constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; address private constant TRI_CRYPTO = 0xc4AD29ba4B3c580e6D59105FFf484999997675Ff; address private constant TRI_CRYPTO_POOL = 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46; address private constant CURVE_ZAP = 0xA79828DF1850E8a3A3064576f380D90aECDD3359; address private constant UNRIPE_CURVE_BEAN_LUSD_POOL = 0xD652c40fBb3f06d6B58Cb9aa9CFF063eE63d465D; address private constant UNRIPE_CURVE_BEAN_METAPOOL = 0x3a70DfA7d2262988064A2D051dd47521E43c9BdD; /** * Getters **/ function getSeasonPeriod() internal pure returns (uint256) { return CURRENT_SEASON_PERIOD; } function getAdvanceIncentive() internal pure returns (uint256) { return BASE_ADVANCE_INCENTIVE; } function getFertilizerDenominator() internal pure returns (uint256) { return FERTILIZER_DENOMINATOR; } function getHarvestDenominator() internal pure returns (uint256) { return HARVEST_DENOMINATOR; } function getChainId() internal pure returns (uint256) { return CHAIN_ID; } function getOptimalPodRate() internal pure returns (Decimal.D256 memory) { return Decimal.ratio(OPTIMAL_POD_RATE, PERCENT_BASE); } function getUpperBoundPodRate() internal pure returns (Decimal.D256 memory) { return Decimal.ratio(POD_RATE_UPPER_BOUND, PERCENT_BASE); } function getLowerBoundPodRate() internal pure returns (Decimal.D256 memory) { return Decimal.ratio(POD_RATE_LOWER_BOUND, PERCENT_BASE); } function getUpperBoundDPD() internal pure returns (Decimal.D256 memory) { return Decimal.ratio(DELTA_POD_DEMAND_UPPER_BOUND, PERCENT_BASE); } function getLowerBoundDPD() internal pure returns (Decimal.D256 memory) { return Decimal.ratio(DELTA_POD_DEMAND_LOWER_BOUND, PERCENT_BASE); } function getSteadySowTime() internal pure returns (uint32) { return STEADY_SOW_TIME; } function getSeedsPerBean() internal pure returns (uint256) { return SEEDS_PER_BEAN; } function getStalkPerBean() internal pure returns (uint256) { return STALK_PER_BEAN; } function getRootsBase() internal pure returns (uint256) { return ROOTS_BASE; } function getSopPrecision() internal pure returns (uint256) { return SOP_PRECISION; } function beanAddress() internal pure returns (address) { return BEAN; } function curveMetapoolAddress() internal pure returns (address) { return CURVE_BEAN_METAPOOL; } function unripeLPPool1() internal pure returns (address) { return UNRIPE_CURVE_BEAN_METAPOOL; } function unripeLPPool2() internal pure returns (address) { return UNRIPE_CURVE_BEAN_LUSD_POOL; } function unripeBeanAddress() internal pure returns (address) { return UNRIPE_BEAN; } function unripeLPAddress() internal pure returns (address) { return UNRIPE_LP; } function unripeBean() internal pure returns (IERC20) { return IERC20(UNRIPE_BEAN); } function unripeLP() internal pure returns (IERC20) { return IERC20(UNRIPE_LP); } function bean() internal pure returns (IBean) { return IBean(BEAN); } function usdc() internal pure returns (IERC20) { return IERC20(USDC); } function curveMetapool() internal pure returns (ICurvePool) { return ICurvePool(CURVE_BEAN_METAPOOL); } function curve3Pool() internal pure returns (I3Curve) { return I3Curve(CURVE_3_POOL); } function curveZap() internal pure returns (ICurveZap) { return ICurveZap(CURVE_ZAP); } function curveZapAddress() internal pure returns (address) { return CURVE_ZAP; } function curve3PoolAddress() internal pure returns (address) { return CURVE_3_POOL; } function threeCrv() internal pure returns (IERC20) { return IERC20(THREE_CRV); } function fertilizer() internal pure returns (IFertilizer) { return IFertilizer(FERTILIZER); } function fertilizerAddress() internal pure returns (address) { return FERTILIZER; } function fertilizerAdmin() internal pure returns (IProxyAdmin) { return IProxyAdmin(FERTILIZER_ADMIN); } function triCryptoPoolAddress() internal pure returns (address) { return TRI_CRYPTO_POOL; } function triCrypto() internal pure returns (IERC20) { return IERC20(TRI_CRYPTO); } function unripeLPPerDollar() internal pure returns (uint256) { return UNRIPE_LP_PER_DOLLAR; } function dollarPerUnripeLP() internal pure returns (uint256) { return 1e12/UNRIPE_LP_PER_DOLLAR; } function exploitAddLPRatio() internal pure returns (uint256) { return ADD_LP_RATIO; } function precision() internal pure returns (uint256) { return PRECISION; } function initialRecap() internal pure returns (uint256) { return INITIAL_HAIRCUT; } function soilCoefficientHigh() internal pure returns (uint256) { return SOIL_COEFFICIENT_HIGH; } function soilCoefficientLow() internal pure returns (uint256) { return SOIL_COEFFICIENT_LOW; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) /******************************************************************************/ interface IDiamondCut { enum FacetCutAction {Add, Replace, Remove} struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../math/SafeMath.sol"; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface ICurvePool { function A_precise() external view returns (uint256); function get_balances() external view returns (uint256[2] memory); function totalSupply() external view returns (uint256); function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external returns (uint256); function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external returns (uint256); function balances(int128 i) external view returns (uint256); function fee() external view returns (uint256); function coins(uint256 i) external view returns (address); function get_virtual_price() external view returns (uint256); function calc_token_amount(uint256[2] calldata amounts, bool deposit) external view returns (uint256); function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external view returns (uint256); function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256); function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); } interface ICurveZap { function add_liquidity(address _pool, uint256[4] memory _deposit_amounts, uint256 _min_mint_amount) external returns (uint256); function calc_token_amount(address _pool, uint256[4] memory _amounts, bool _is_deposit) external returns (uint256); } interface ICurvePoolR { function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256); function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy, address receiver) external returns (uint256); function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount, address receiver) external returns (uint256); } interface ICurvePool2R { function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[2] memory _min_amounts, address reciever) external returns (uint256[2] calldata); function remove_liquidity_imbalance(uint256[2] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface ICurvePool3R { function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[3] memory _min_amounts, address reciever) external returns (uint256[3] calldata); function remove_liquidity_imbalance(uint256[3] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface ICurvePool4R { function add_liquidity(uint256[4] memory amounts, uint256 min_mint_amount, address reciever) external returns (uint256); function remove_liquidity(uint256 _burn_amount, uint256[4] memory _min_amounts, address reciever) external returns (uint256[4] calldata); function remove_liquidity_imbalance(uint256[4] memory _amounts, uint256 _max_burn_amount, address reciever) external returns (uint256); } interface I3Curve { function get_virtual_price() external view returns (uint256); } interface ICurveFactory { function get_coins(address _pool) external view returns (address[4] calldata); function get_underlying_coins(address _pool) external view returns (address[8] calldata); } interface ICurveCryptoFactory { function get_coins(address _pool) external view returns (address[8] calldata); } interface ICurvePoolC { function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256); } interface ICurvePoolNoReturn { function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external; function add_liquidity(uint256[3] memory amounts, uint256 min_mint_amount) external; function remove_liquidity(uint256 _burn_amount, uint256[3] memory _min_amounts) external; function remove_liquidity_imbalance(uint256[3] memory _amounts, uint256 _max_burn_amount) external; function remove_liquidity_one_coin(uint256 _token_amount, uint256 i, uint256 min_amount) external; } interface ICurvePoolNoReturn128 { function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external; function remove_liquidity_one_coin(uint256 _token_amount, int128 i, uint256 min_amount) external; }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface IFertilizer { struct Balance { uint128 amount; uint128 lastBpf; } function beanstalkUpdate( address account, uint256[] memory ids, uint128 bpf ) external returns (uint256); function beanstalkMint(address account, uint256 id, uint128 amount, uint128 bpf) external; function balanceOfFertilized(address account, uint256[] memory ids) external view returns (uint256); function balanceOfUnfertilized(address account, uint256[] memory ids) external view returns (uint256); function lastBalanceOf(address account, uint256 id) external view returns (Balance memory); function lastBalanceOfBatch(address[] memory account, uint256[] memory id) external view returns (Balance[] memory); function setURI(string calldata newuri) external; }
// SPDX-License-Identifier: MIT pragma experimental ABIEncoderV2; pragma solidity =0.7.6; interface IProxyAdmin { function upgrade(address proxy, address implementation) external; }
/* SPDX-License-Identifier: MIT */ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; /** * @title Decimal * @author dYdX * * Library that defines a fixed-point number with 18 decimal places. */ library Decimal { using SafeMath for uint256; // ============ Constants ============ uint256 constant BASE = 10**18; // ============ Structs ============ struct D256 { uint256 value; } // ============ Static Functions ============ function zero() internal pure returns (D256 memory) { return D256({ value: 0 }); } function one() internal pure returns (D256 memory) { return D256({ value: BASE }); } function from( uint256 a ) internal pure returns (D256 memory) { return D256({ value: a.mul(BASE) }); } function ratio( uint256 a, uint256 b ) internal pure returns (D256 memory) { return D256({ value: getPartial(a, BASE, b) }); } // ============ Self Functions ============ function add( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.add(b.mul(BASE)) }); } function sub( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.mul(BASE)) }); } function sub( D256 memory self, uint256 b, string memory reason ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.mul(BASE), reason) }); } function mul( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.mul(b) }); } function div( D256 memory self, uint256 b ) internal pure returns (D256 memory) { return D256({ value: self.value.div(b) }); } function pow( D256 memory self, uint256 b ) internal pure returns (D256 memory) { if (b == 0) { return one(); } D256 memory temp = D256({ value: self.value }); for (uint256 i = 1; i < b; ++i) { temp = mul(temp, self); } return temp; } function add( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: self.value.add(b.value) }); } function sub( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.value) }); } function sub( D256 memory self, D256 memory b, string memory reason ) internal pure returns (D256 memory) { return D256({ value: self.value.sub(b.value, reason) }); } function mul( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: getPartial(self.value, b.value, BASE) }); } function div( D256 memory self, D256 memory b ) internal pure returns (D256 memory) { return D256({ value: getPartial(self.value, BASE, b.value) }); } function equals(D256 memory self, D256 memory b) internal pure returns (bool) { return self.value == b.value; } function greaterThan(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) == 2; } function lessThan(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) == 0; } function greaterThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) > 0; } function lessThanOrEqualTo(D256 memory self, D256 memory b) internal pure returns (bool) { return compareTo(self, b) < 2; } function isZero(D256 memory self) internal pure returns (bool) { return self.value == 0; } function asUint256(D256 memory self) internal pure returns (uint256) { return self.value.div(BASE); } // ============ Core Methods ============ function getPartial( uint256 target, uint256 numerator, uint256 denominator ) private pure returns (uint256) { return target.mul(numerator).div(denominator); } function compareTo( D256 memory a, D256 memory b ) private pure returns (uint256) { if (a.value == b.value) { return 1; } return a.value > b.value ? 2 : 0; } }
/* SPDX-License-Identifier: MIT */ pragma solidity ^0.7.6; pragma experimental ABIEncoderV2; import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/Math.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/SafeCast.sol"; import "../LibAppStorage.sol"; /** * @author LeoFib, Publius * @title LibInternalBalance Library handles internal read/write functions for Internal User Balances. * Largely inspired by Balancer's Vault **/ library LibBalance { using SafeERC20 for IERC20; using SafeMath for uint256; using SafeCast for uint256; /** * @dev Emitted when a account's Internal Balance changes, through interacting using Internal Balance. * */ event InternalBalanceChanged( address indexed account, IERC20 indexed token, int256 delta ); function getBalance(address account, IERC20 token) internal view returns (uint256 combined_balance) { combined_balance = token.balanceOf(account).add( getInternalBalance(account, token) ); return combined_balance; } /** * @dev Increases `account`'s Internal Balance for `token` by `amount`. */ function increaseInternalBalance( address account, IERC20 token, uint256 amount ) internal { uint256 currentBalance = getInternalBalance(account, token); uint256 newBalance = currentBalance.add(amount); setInternalBalance(account, token, newBalance, amount.toInt256()); } /** * @dev Decreases `account`'s Internal Balance for `token` by `amount`. If `allowPartial` is true, this function * doesn't revert if `account` doesn't have enough balance, and sets it to zero and returns the deducted amount * instead. */ function decreaseInternalBalance( address account, IERC20 token, uint256 amount, bool allowPartial ) internal returns (uint256 deducted) { uint256 currentBalance = getInternalBalance(account, token); require( allowPartial || (currentBalance >= amount), "Balance: Insufficient internal balance" ); deducted = Math.min(currentBalance, amount); // By construction, `deducted` is lower or equal to `currentBalance`, so we don't need to use checked // arithmetic. uint256 newBalance = currentBalance - deducted; setInternalBalance(account, token, newBalance, -(deducted.toInt256())); } /** * @dev Sets `account`'s Internal Balance for `token` to `newBalance`. * * Emits an `InternalBalanceChanged` event. This event includes `delta`, which is the amount the balance increased * (if positive) or decreased (if negative). To avoid reading the current balance in order to compute the delta, * this function relies on the caller providing it directly. */ function setInternalBalance( address account, IERC20 token, uint256 newBalance, int256 delta ) private { AppStorage storage s = LibAppStorage.diamondStorage(); s.internalTokenBalance[account][token] = newBalance; emit InternalBalanceChanged(account, token, delta); } /** * @dev Returns `account`'s Internal Balance for `token`. */ function getInternalBalance(address account, IERC20 token) internal view returns (uint256) { AppStorage storage s = LibAppStorage.diamondStorage(); return s.internalTokenBalance[account][token]; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ 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)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length 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)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
/* SPDX-License-Identifier: MIT */ pragma solidity =0.7.6; pragma experimental ABIEncoderV2; import "../farm/AppStorage.sol"; /** * @author Publius * @title App Storage Library allows libaries to access Beanstalk's state. **/ library LibAppStorage { function diamondStorage() internal pure returns (AppStorage storage ds) { assembly { ds.slot := 0 } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ 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"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ 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"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (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 { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pods","type":"uint256"}],"name":"PlotTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"pods","type":"uint256"}],"name":"PodApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"PodListingCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"indexed":false,"internalType":"uint256","name":"maxHarvestableIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"indexed":false,"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"},{"indexed":false,"internalType":"enum LibPolynomial.PriceType","name":"pricingType","type":"uint8"}],"name":"PodListingCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"costInBeans","type":"uint256"}],"name":"PodListingFilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"PodOrderCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"indexed":false,"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"indexed":false,"internalType":"enum LibPolynomial.PriceType","name":"priceType","type":"uint8"}],"name":"PodOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"costInBeans","type":"uint256"}],"name":"PodOrderFilled","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowancePods","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approvePods","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"cancelPodListing","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"cancelPodOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"cancelPodOrderV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxHarvestableIndex","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"createPodListing","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"maxHarvestableIndex","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"createPodListingV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"beanAmount","type":"uint256"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"enum LibTransfer.From","name":"mode","type":"uint8"}],"name":"createPodOrder","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"beanAmount","type":"uint256"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"internalType":"enum LibTransfer.From","name":"mode","type":"uint8"}],"name":"createPodOrderV2","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxHarvestableIndex","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"internalType":"struct Listing.PodListing","name":"l","type":"tuple"},{"internalType":"uint256","name":"beanAmount","type":"uint256"},{"internalType":"enum LibTransfer.From","name":"mode","type":"uint8"}],"name":"fillPodListing","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxHarvestableIndex","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"internalType":"struct Listing.PodListing","name":"l","type":"tuple"},{"internalType":"uint256","name":"beanAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"internalType":"enum LibTransfer.From","name":"mode","type":"uint8"}],"name":"fillPodListingV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"}],"internalType":"struct Order.PodOrder","name":"o","type":"tuple"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"fillPodOrder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"}],"internalType":"struct Order.PodOrder","name":"o","type":"tuple"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"},{"internalType":"enum LibTransfer.To","name":"mode","type":"uint8"}],"name":"fillPodOrderV2","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"placeInLine","type":"uint256"},{"internalType":"uint256","name":"amountPodsFromOrder","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"}],"name":"getAmountBeansToFillOrderV2","outputs":[{"internalType":"uint256","name":"beanAmount","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"placeInLine","type":"uint256"},{"internalType":"uint256","name":"podListingAmount","type":"uint256"},{"internalType":"uint256","name":"fillBeanAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"}],"name":"getAmountPodsFromFillListingV2","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"podListing","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint24","name":"pricePerPod","type":"uint24"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"}],"name":"podOrder","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"podOrderById","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"maxPlaceInLine","type":"uint256"},{"internalType":"uint256","name":"minFillAmount","type":"uint256"},{"internalType":"bytes","name":"pricingFunction","type":"bytes"}],"name":"podOrderV2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"transferPlot","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613fcf806100206000396000f3fe60806040526004361061015f5760003560e01c8063845a022b116100c0578063c5644a6011610074578063df18a3ee11610059578063df18a3ee1461031a578063eda8156e1461032d578063f22b49ec146103405761015f565b8063c5644a60146102e7578063d6af17ab146102fa5761015f565b8063a99d840c116100a5578063a99d840c14610294578063b1719e59146102a7578063c3e14715146102c75761015f565b8063845a022b1461026e578063a8f135a2146102815761015f565b806369d9120d1161011757806380bd7d33116100fc57806380bd7d331461023557806382c6512414610248578063836019921461025b5761015f565b806369d9120d146102025780637e2a1fd1146102155761015f565b80630b385a85116101485780630b385a85146101ba5780633260c49e146101da5780634214861e146101ef5761015f565b8063042ff31d14610164578063045d57631461019a575b600080fd5b34801561017057600080fd5b5061018461017f366004612f76565b610353565b60405161019191906136e4565b60405180910390f35b3480156101a657600080fd5b506101846101b5366004612fe0565b61037e565b3480156101c657600080fd5b506101846101d5366004612ef8565b6103ab565b6101ed6101e8366004613046565b6103dc565b005b6101ed6101fd366004613129565b6103e9565b6101ed610210366004612f2a565b610401565b34801561022157600080fd5b506101846102303660046132ab565b61054a565b6101ed610243366004613406565b610579565b610184610256366004613268565b610588565b610184610269366004613398565b6105b5565b6101ed61027c3660046131ac565b6105e4565b6101ed61028f36600461345a565b6105f8565b6101ed6102a2366004613078565b610612565b3480156102b357600080fd5b506101846102c2366004613046565b610651565b3480156102d357600080fd5b506101846102e2366004613356565b610666565b6101ed6102f5366004612fb7565b6106d9565b34801561030657600080fd5b50610184610315366004613046565b610786565b6101ed61032836600461320b565b610798565b6101ed61033b3660046130ea565b6107aa565b6101ed61034e3660046132fc565b6107e7565b6000603781610364878787876107f4565b81526020019081526020016000205490505b949350505050565b6000603781610391888289898989610865565b815260200190815260200160002054905095945050505050565b6001600160a01b03808316600090815260316020908152604080832093851683526001909301905220545b92915050565b6103e633826108e2565b50565b6103f88787878787878761097a565b50505050505050565b601e546002141561042d5760405162461bcd60e51b815260040161042490613d09565b60405180910390fd5b6002601e556001600160a01b0385161580159061045257506001600160a01b03841615155b61046e5760405162461bcd60e51b8152600401610424906137b8565b6001600160a01b0385166000908152603160209081526040808320868452909152902054806104af5760405162461bcd60e51b815260040161042490613b01565b82821180156104be5750818110155b6104da5760405162461bcd60e51b8152600401610424906139d9565b50818103336001600160a01b0387161480159061050257506000196104ff87336103ab565b14155b1561051257610512863383610b83565b600084815260366020526040902054156105305761053086856108e2565b61053d8686868685610be5565b50506001601e5550505050565b600061056183838761055c8189610c9c565b610cfd565b905061057081620f4240610e1c565b95945050505050565b6103f887878787878787610e83565b600061059d610595610fae565b873385610fc6565b95506105ab8686868661114a565b9695505050505050565b60006105ca6105c2610fae565b883385610fc6565b96506105d98787878787611220565b979650505050505050565b6105f185858585856112d6565b5050505050565b61060888888888888888886114e8565b5050505050505050565b61064361061d610fae565b3361062b6020890189612ede565b878561063e6101008c0160e08d0161305e565b6115de565b93506105f1858585856116fd565b6000818152603760205260409020545b919050565b600080610674848489611878565b90508061068486620f42406118d2565b8161068b57fe5b04915060006106b583604051806060016040528060288152602001613f486028913989919061192b565b905081620f4240816106c357fe5b0481116106ce578692505b505095945050505050565b601e54600214156106fc5760405162461bcd60e51b815260040161042490613d09565b6002601e556001600160a01b0382166107275760405162461bcd60e51b815260040161042490613947565b6107323383836119c2565b816001600160a01b0316336001600160a01b03167f2602b28af334328fb380d7416219c5cd9c3c8a0cacda4fb8e090c56557477d488360405161077591906136e4565b60405180910390a350506001601e55565b60009081526036602052604090205490565b6107a4848484846119f2565b50505050565b6107d66107b5610fae565b336107c36020870187612ede565b858561063e6101008a0160e08b0161305e565b91506107e28383611a70565b505050565b6105f18585858585611bda565b6000811561083057848484846040516020016108139493929190613588565b604051602081830303815290604052805190602001209050610376565b84848460405160200161084593929190613551565b604051602081830303815290604052805190602001209050949350505050565b6000610887602061088160a861087b8787611c5c565b906118d2565b90610c9c565b82146108a55760405162461bcd60e51b815260040161042490613872565b8686868686866040516020016108c0969594939291906135c4565b6040516020818303038152906040528051906020012090509695505050505050565b6001600160a01b03821660009081526031602090815260408083208484529091529020546109225760405162461bcd60e51b815260040161042490613815565b60008181526036602052604080822091909155516001600160a01b038316907fe9dc43fcbeb08ecb743b537fa98567049e3b77e283833f89ab216b22ede6ba0a9061096e9084906136e4565b60405180910390a25050565b866060013584101561099e5760405162461bcd60e51b815260040161042490613b95565b6109a88585610c9c565b3360009081526031602090815260408083208a845290915290205410156109e15760405162461bcd60e51b815260040161042490613a6d565b600e54604088013590610a02906109fc876108818b8b610c9c565b90611c75565b1115610a205760405162461bcd60e51b815260040161042490613c4f565b6000610a45610a3260208a018a612ede565b60008a604001358b606001358888610865565b600e54909150600090610a6890610a60906109fc8b8b610c9c565b87878761054a565b9050610a9d81604051806060016040528060278152602001613e8360279139600085815260376020526040902054919061192b565b600083815260376020526040902055610abf610ab7610fae565b823386611cd2565b60008881526036602052604090205415610add57610add33896108e2565b610af633610aee60208c018c612ede565b8a8a8a610be5565b600082815260376020526040902054610b19576000828152603760205260408120555b610b2660208a018a612ede565b6001600160a01b0316336001600160a01b03167f525994627282299f72de05d7d3f543c6ec6c2022cb3898ad47ff18553c7655bf848b8b8b87604051610b70959493929190613795565b60405180910390a3505050505050505050565b6000610b8f84846103ab565b90506107a48484610be0856040518060400160405280601d81526020017f4669656c643a20496e73756666696369656e7420617070726f76616c2e0000008152508661192b9092919063ffffffff16565b6119c2565b836001600160a01b0316856001600160a01b03161415610c175760405162461bcd60e51b815260040161042490613b38565b610c2b84610c258585610c9c565b83611d14565b610c40858484610c3b8582610c9c565b611d3a565b610c4a8383610c9c565b846001600160a01b0316866001600160a01b03167fed4f3f107ad11834ddcfa24bee36362f72a9f0301995380177a0efb5b21c3d5984604051610c8d91906136e4565b60405180910390a45050505050565b600082820183811015610cf6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600080610d0a8686611c5c565b90506000610d1a87878785611dff565b90506000610d29888884611e76565b90506000610d3b898985600101611e76565b905060005b80610e0f5781871115610d5557506000610d59565b5060015b6000610d80846040518060600160405280602b8152602001613ecb602b91398b919061192b565b9050600082610d9857610d938486611c75565b610da2565b610da28986611c75565b9050610dbc610db58d8d898b8787611e99565b8990610c9c565b975082610e085783995060018703861415610dda5760019250610e08565b600190950194610deb8c8c88611e76565b9450600187038614610e0857610e058c8c88600101611e76565b93505b5050610d40565b5050505050949350505050565b6000808211610e72576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610e7b57fe5b049392505050565b3360009081526031602090815260408083208a8452909152902054610ea88787610c9c565b8110158015610eb75750600086115b610ed35760405162461bcd60e51b815260040161042490613d40565b60008562ffffff1611610ef85760405162461bcd60e51b815260040161042490613aa4565b600e54841015610f1a5760405162461bcd60e51b8152600401610424906138cf565b60008881526036602052604090205415610f3857610f3833896108e2565b610f46878787878787612002565b60008981526036602052604080822092909255905160609133917fb7653814153cbbed10e29f56c0ba102e97b4ce1078bbd8bd02da1ccce7d38fc991610f9b918d918d918d918d918d918d918b918e91613df0565b60405180910390a2505050505050505050565b73bea0000029ad1c77d3d5d23ba2d8893db9d1efab90565b600083610fd557506000610376565b6000826003811115610fe357fe5b14611028576110038386866001866003811115610ffc57fe5b1415612077565b90508084148061101e5750600382600381111561101c57fe5b145b1561102857610376565b6040516370a0823160e01b81526000906001600160a01b038716906370a08231906110579030906004016136d0565b60206040518083038186803b15801561106f57600080fd5b505afa158015611083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a79190613250565b90506110c06001600160a01b03871685308589036120de565b6105ab61114382886001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110f391906136d0565b60206040518083038186803b15801561110b57600080fd5b505afa15801561111f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fc9190613250565b8390610c9c565b600080851161116b5760405162461bcd60e51b815260040161042490613a10565b60008462ffffff16116111905760405162461bcd60e51b815260040161042490613aa4565b61119c338585856107f4565b600081815260376020526040902054909150156111c0576111c084848460016119f2565b6000818152603760205260408082208790555160609133917f7279c7b5d64f6bb98758727f0f16bcc5cf260997bfb49a45234c28fcb55fbcf09161120f9186918b918b918b918b918a91613742565b60405180910390a250949350505050565b60008086116112415760405162461bcd60e51b815260040161042490613a10565b61125033600087878787610865565b6000818152603760205260409020549091501561127557611275858585856001611bda565b6000818152603760205260408082208890555133917f7279c7b5d64f6bb98758727f0f16bcc5cf260997bfb49a45234c28fcb55fbcf0916112c59185918b91908b908b908b908b906001906136ed565b60405180910390a295945050505050565b84606001358210156112fa5760405162461bcd60e51b815260040161042490613b95565b6113048383610c9c565b336000908152603160209081526040808320888452909152902054101561133d5760405162461bcd60e51b815260040161042490613a6d565b600e54604086013590611358906109fc856108818989610c9c565b11156113765760405162461bcd60e51b815260040161042490613c4f565b60006113a76113886020880188612ede565b6113986040890160208a016131f1565b886040013589606001356107f4565b905060006113d7620f42406113d16113c560408b0160208c016131f1565b879062ffffff166118d2565b90610e1c565b905061140c81604051806060016040528060278152602001613e8360279139600085815260376020526040902054919061192b565b600083815260376020526040902055611426610ab7610fae565b600086815260366020526040902054156114445761144433876108e2565b61145d3361145560208a018a612ede565b888888610be5565b600082815260376020526040902054611480576000828152603760205260408120555b61148d6020880188612ede565b6001600160a01b0316336001600160a01b03167f525994627282299f72de05d7d3f543c6ec6c2022cb3898ad47ff18553c7655bf84898989876040516114d7959493929190613795565b60405180910390a350505050505050565b3360009081526031602090815260408083208b845290915290205461150d8888610c9c565b811015801561151c5750600087115b6115385760405162461bcd60e51b815260040161042490613d40565b600e5486101561155a5760405162461bcd60e51b8152600401610424906138cf565b6000898152603660205260409020541561157857611578338a6108e2565b611589888860008989898989612166565b60008a81526036602052604080822092909255905133917fb7653814153cbbed10e29f56c0ba102e97b4ce1078bbd8bd02da1ccce7d38fc991610f9b918d918d918d918d908d908d908d908d90600190613d81565b6000808360038111156115ed57fe5b1480156116055750600082600181111561160357fe5b145b156116d8576040516370a0823160e01b81526000906001600160a01b038916906370a08231906116399089906004016136d0565b60206040518083038186803b15801561165157600080fd5b505afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613250565b90506116a06001600160a01b0389168888886120de565b6116d081896001600160a01b03166370a08231896040518263ffffffff1660e01b81526004016110f391906136d0565b9150506105ab565b6116e487858886610fc6565b93506116f287858785611cd2565b509195945050505050565b600061173e6040860135606087013561171c60a0890160808a016131f1565b60a089013560c08a013588886117396101008e0160e08f0161305e565b612166565b60208087013560009081526036909152604090205490915081146117745760405162461bcd60e51b815260040161042490613bf2565b60006031816117866020890189612ede565b6001600160a01b0316815260208082019290925260409081016000908120898401358252909252908190205491506117c5908701356060880135610c9c565b81101580156117d8575060008660600135115b6117f45760405162461bcd60e51b815260040161042490613d40565b600e5460a0870135101561181a5760405162461bcd60e51b815260040161042490613906565b600e546000906118479061183a906109fc60208b013560408c0135610c9c565b8860600135888888610666565b905061185733888787858b6121eb565b6103f86118676020890189612ede565b3389602001358a6040013585610be5565b6000806118858585611c5c565b9050600061189586868685611dff565b90506105ab868683856118cd6118ac8c8c89611e76565b6040518060600160405280602a8152602001613ef6602a91398b919061192b565b61232d565b6000826118e1575060006103d6565b828202828482816118ee57fe5b0414610cf65760405162461bcd60e51b8152600401808060200182810382526021815260200180613eaa6021913960400191505060405180910390fd5b600081848411156119ba5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561197f578181015183820152602001611967565b50505050905090810190601f1680156119ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b039283166000908152603160209081526040808320949095168252600190930190925291902055565b6000611a00338686866107f4565b600081815260376020526040902054909150611a1d610ab7610fae565b600082815260376020526040808220919091555133907f531180eb4d1153cb99f00e54fef0a473edc9e3e951f9a88468fec65988e9e4f890611a609085906136e4565b60405180910390a2505050505050565b6000611aaf60408401356060850135611a8f60a08701608088016131f1565b60a087013560c0880135611aaa6101008a0160e08b0161305e565b612002565b6020808501356000908152603690915260409020549091508114611ae55760405162461bcd60e51b815260040161042490613bf2565b6000603181611af76020870187612ede565b6001600160a01b031681526020808201929092526040908101600090812087840135825290925290819020549150611b36908501356060860135610c9c565b8110158015611b49575060008460600135115b611b655760405162461bcd60e51b815260040161042490613d40565b600e5460a08501351015611b8b5760405162461bcd60e51b815260040161042490613906565b6000611bab611ba060a08701608088016131f1565b8660600135866123fa565b9050611bb933868387612464565b6105f1611bc96020870187612ede565b338760200135886040013585610be5565b6000611beb33600088888888610865565b600081815260376020526040902054909150611c08610ab7610fae565b600082815260376020526040808220919091555133907f531180eb4d1153cb99f00e54fef0a473edc9e3e951f9a88468fec65988e9e4f890611c4b9085906136e4565b60405180910390a250505050505050565b6000610cf681611c6f8585836020612587565b90612640565b600082821115611ccc576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b82611cdc576107a4565b6001816001811115611cea57fe5b1415611d0057611cfb8285856126fc565b6107a4565b6107a46001600160a01b038516838561272c565b6001600160a01b0390921660009081526031602090815260408083209383529290522055565b6001600160a01b038416600090815260316020908152604080832086845290915290205482611d8c576001600160a01b0385166000908152603160209081526040808320878452909152812055611db3565b6001600160a01b038516600090815260316020908152604080832087845290915290208390555b8082146105f157611dc48183611c75565b6001600160a01b038616600090815260316020526040812090611de78786610c9c565b81526020810191909152604001600020555050505050565b600080611e0e86866000611e76565b905080841015611e22576000915050610376565b60005b83811015611e685784821415611e3e5791506103769050565b84821115611e53576000190191506103769050565b600101611e61878783611e76565b9150611e25565b600019019695505050505050565b600061037681611c6f611e8e602061088187826118d2565b879087906020612587565b600080600080611eab8a8a8a8a6127ac565b90506000611ebb8b8b8b8b612829565b90506000611ecb8c8c8c8c6128b3565b905060005b60038111611fe757818160048110611ee457fe5b602002015115611f9057611f41611f3a611f198360010161087b600a888760048110611f0c57fe5b602002015160ff1661297e565b6113d1878560048110611f2857fe5b602002015161087b8d8760010161297e565b8790610c9c565b9550611f89611f82611f618360010161087b600a888760048110611f0c57fe5b6113d1878560048110611f7057fe5b602002015161087b8e8760010161297e565b8790611c75565b9550611fdf565b611fb5611fae611f198360010161087b600a888760048110611f0c57fe5b8690610c9c565b9450611fdc611fd5611f618360010161087b600a888760048110611f0c57fe5b8690611c75565b94505b600101611ed0565b50611ff28585611c75565b9c9b505050505050505050505050565b60008215612050578686868686600087600181111561201d57fe5b1460405160200161203396959493929190613647565b6040516020818303038152906040528051906020012090506105ab565b86868686600086600181111561206257fe5b146040516020016108c0959493929190613612565b60008061208486866129df565b905082806120925750838110155b6120ae5760405162461bcd60e51b81526004016104249061397c565b6120b88185612a1b565b91508181036120d48787836120cc87612a31565b600003612a95565b5050949350505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526107a4908590612b10565b600061217c602061088160a861087b8888611c5c565b831461219a5760405162461bcd60e51b815260040161042490613872565b888888888860008760018111156121ad57fe5b1489896040516020016121c7989796959493929190613681565b60405160208183030381529060405280519060200120905098975050505050505050565b8460c0013582101561220f5760405162461bcd60e51b815260040161042490613b95565b81856060013510156122335760405162461bcd60e51b815260040161042490613cac565b60208086013560009081526036909152604081205560608501358210156122c0576122946000612267606088013585611c75565b61227760a0890160808a016131f1565b60a089013560c08a013589896117396101008e0160e08f0161305e565b603660006122ae604089013561088160208b013588610c9c565b81526020810191909152604001600020555b6001600160a01b0386166122d76020870187612ede565b6001600160a01b03167fb33a5c3dd7c4265e5702ad84b5c4f6bb3971d2424a47955979a642fe9d77f4c387602001358860400135868660405161231d9493929190613e5d565b60405180910390a3505050505050565b60008060008061233f898989896127ac565b9050600061234f8a8a8a8a612829565b9050600061235f8b8b8b8b6128b3565b905060005b600381116123e05781816004811061237857fe5b6020020151156123be576123b7611f3a612399600a868560048110611f0c57fe5b6113d18785600481106123a857fe5b602002015161087b8d8761297e565b95506123d8565b6123d5611fae612399600a868560048110611f0c57fe5b94505b600101612364565b506123eb8585611c75565b9b9a5050505050505050505050565b60008362ffffff1682620f4240028161240f57fe5b049050600061243982604051806060016040528060288152602001613f486028913986919061192b565b90508462ffffff16620f42408161244c57fe5b0462ffffff16811161245c578391505b509392505050565b8260c001358210156124885760405162461bcd60e51b815260040161042490613b95565b81836060013510156124ac5760405162461bcd60e51b815260040161042490613cac565b602080840135600090815260369091526040812055606083013582101561251c576124f060006124e0606086013585611c75565b611a8f60a08701608088016131f1565b6036600061250a6040870135610881602089013588610c9c565b81526020810191909152604001600020555b6001600160a01b0384166125336020850185612ede565b6001600160a01b03167fb33a5c3dd7c4265e5702ad84b5c4f6bb3971d2424a47955979a642fe9d77f4c38560200135866040013586866040516125799493929190613e5d565b60405180910390a350505050565b606060008267ffffffffffffffff811180156125a257600080fd5b506040519080825280601f01601f1916602001820160405280156125cd576020820181803683370190505b50905060005b838110156126365786868287018181106125e957fe5b9050013560f81c60f81b8282815181106125ff57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016125d3565b5095945050505050565b60008182602001101561269a576040805162461bcd60e51b815260206004820152601260248201527f746f55696e743235365f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81602001835110156126f3576040805162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b50016020015190565b600061270884846129df565b905060006127168284610c9c565b90506105f185858361272787612a31565b612a95565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107e2908490612b10565b6127b4612e08565b60006127e16127d660206108816127cb87836118d2565b6108818960806118d2565b879087906080612587565b90506127ee816000612640565b82526127fb816020612640565b602083015261280b816040612640565b604083015261281b816060612640565b606083015250949350505050565b612831612e08565b600061285f61285460206108816128498760a06118d2565b6108818960046118d2565b879087906004612587565b905061286c816000612bc1565b60ff16825261287c816001612bc1565b60ff16602083015261288f816002612bc1565b60ff1660408301526128a2816003612bc1565b60ff16606083015250949350505050565b6128bb612e08565b60006128d361285460206108816128498760a46118d2565b90506128e0816000612bc1565b60ff16600114826000600481106128f357fe5b91151560209092020152612908816001612bc1565b60ff166001148260016004811061291b57fe5b91151560209092020152612930816002612bc1565b60ff166001148260026004811061294357fe5b91151560209092020152612958816003612bc1565b60ff166001148260036004811061296b57fe5b9115156020909202015250949350505050565b60008161298d575060016103d6565b816001141561299d5750816103d6565b821580156129aa57508115155b156129b7575060006103d6565b8260015b838110156129d7576129cd82866118d2565b91506001016129bb565b5090506103d6565b6000806129ea612c7d565b6001600160a01b039485166000908152603e9190910160209081526040808320959096168252939093525050205490565b6000818310612a2a5781610cf6565b5090919050565b60007f80000000000000000000000000000000000000000000000000000000000000008210612a915760405162461bcd60e51b8152600401808060200182810382526028815260200180613f206028913960400191505060405180910390fd5b5090565b6000612a9f612c7d565b6001600160a01b038087166000818152603e840160209081526040808320948a1680845294909152908190208790555192935090917f18e1ea4139e68413d7d08aa752e71568e36b2c5bf940893314c2c5b01eaa0c4290612b019086906136e4565b60405180910390a35050505050565b6000612b65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612c829092919063ffffffff16565b8051909150156107e257808060200190516020811015612b8457600080fd5b50516107e25760405162461bcd60e51b815260040180806020018281038252602a815260200180613f70602a913960400191505060405180910390fd5b600081826001011015612c1b576040805162461bcd60e51b815260206004820152601060248201527f746f55696e74385f6f766572666c6f7700000000000000000000000000000000604482015290519081900360640190fd5b8160010183511015612c74576040805162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e647300000000000000000000000000604482015290519081900360640190fd5b50016001015190565b600090565b6060610376848460008585612c9685612d9c565b612ce7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310612d255780518252601f199092019160209182019101612d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612d87576040519150601f19603f3d011682016040523d82523d6000602084013e612d8c565b606091505b50915091506105d9828286612da2565b3b151590565b60608315612db1575081610cf6565b825115612dc15782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561197f578181015183820152602001611967565b60405180608001604052806004906020820280368337509192915050565b80356001600160a01b038116811461066157600080fd5b60008083601f840112612e4e578182fd5b50813567ffffffffffffffff811115612e65578182fd5b602083019150836020828501011115612e7d57600080fd5b9250929050565b80356004811061066157600080fd5b80356002811061066157600080fd5b60006101008284031215612eb4578081fd5b50919050565b600060808284031215612eb4578081fd5b803562ffffff8116811461066157600080fd5b600060208284031215612eef578081fd5b610cf682612e26565b60008060408385031215612f0a578081fd5b612f1383612e26565b9150612f2160208401612e26565b90509250929050565b600080600080600060a08688031215612f41578081fd5b612f4a86612e26565b9450612f5860208701612e26565b94979496505050506040830135926060810135926080909101359150565b60008060008060808587031215612f8b578384fd5b612f9485612e26565b9350612fa260208601612ecb565b93969395505050506040820135916060013590565b60008060408385031215612fc9578182fd5b612fd283612e26565b946020939093013593505050565b600080600080600060808688031215612ff7578081fd5b61300086612e26565b94506020860135935060408601359250606086013567ffffffffffffffff811115613029578182fd5b61303588828901612e3d565b969995985093965092949392505050565b600060208284031215613057578081fd5b5035919050565b60006020828403121561306f578081fd5b610cf682612e93565b60008060008060006101608688031215613090578081fd5b61309a8787612ea2565b9450610100860135935061012086013567ffffffffffffffff8111156130be578182fd5b6130ca88828901612e3d565b90945092506130de90506101408701612e84565b90509295509295909350565b600080600061014084860312156130ff578283fd5b6131098585612ea2565b925061010084013591506131206101208501612e84565b90509250925092565b6000806000806000806000610120888a031215613144578485fd5b61314e8989612eba565b96506080880135955060a0880135945060c0880135935060e088013567ffffffffffffffff81111561317e578283fd5b61318a8a828b01612e3d565b909450925061319e90506101008901612e93565b905092959891949750929550565b600080600080600061010086880312156131c4578283fd5b6131ce8787612eba565b94506080860135935060a0860135925060c086013591506130de60e08701612e93565b600060208284031215613202578081fd5b610cf682612ecb565b60008060008060808587031215613220578182fd5b61322985612ecb565b9350602085013592506040850135915061324560608601612e93565b905092959194509250565b600060208284031215613261578081fd5b5051919050565b600080600080600060a0868803121561327f578283fd5b8535945061328f60208701612ecb565b935060408601359250606086013591506130de60808701612e84565b600080600080606085870312156132c0578182fd5b8435935060208501359250604085013567ffffffffffffffff8111156132e4578283fd5b6132f087828801612e3d565b95989497509550505050565b600080600080600060808688031215613313578283fd5b8535945060208601359350604086013567ffffffffffffffff811115613337578384fd5b61334388828901612e3d565b90945092506130de905060608701612e93565b60008060008060006080868803121561336d578283fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613029578182fd5b60008060008060008060a087890312156133b0578384fd5b863595506020870135945060408701359350606087013567ffffffffffffffff8111156133db578283fd5b6133e789828a01612e3d565b90945092506133fa905060808801612e84565b90509295509295509295565b600080600080600080600060e0888a031215613420578081fd5b87359650602088013595506040880135945061343e60608901612ecb565b93506080880135925060a0880135915061319e60c08901612e93565b60008060008060008060008060e0898b031215613475578182fd5b883597506020890135965060408901359550606089013594506080890135935060a089013567ffffffffffffffff8111156134ae578283fd5b6134ba8b828c01612e3d565b90945092506134cd905060c08a01612e93565b90509295985092959890939650565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b8181101561352b5760208185018101518683018201520161350f565b8181111561353c5782602083870101525b50601f01601f19169290920160200192915050565b60609390931b6bffffffffffffffffffffffff1916835260e89190911b6001600160e81b0319166014830152601782015260370190565b60609490941b6bffffffffffffffffffffffff1916845260e89290921b6001600160e81b03191660148401526017830152603782015260570190565b60006bffffffffffffffffffffffff198860601b1682526001600160e81b03198760e81b16601483015285601783015284603783015282846057840137910160570190815295945050505050565b948552602085019390935260e89190911b6001600160e81b03191660408401526043830152151560f81b606382015260640190565b958652602086019490945260e89290921b6001600160e81b031916604085015260438401526063830152151560f81b608382015260840190565b60008982528860208301526001600160e81b03198860e81b16604083015286604383015285606383015284151560f81b6083830152828460848401379101608401908152979650505050505050565b6001600160a01b0391909116815260200190565b90815260200190565b600089825288602083015262ffffff8816604083015286606083015285608083015260e060a083015261372460e0830185876134dc565b905061372f83613e78565b8260c08301529998505050505050505050565b600088825287602083015262ffffff8716604083015285606083015284608083015260e060a083015261377860e0830185613506565b905061378383613e78565b8260c083015298975050505050505050565b948552602085019390935260408401919091526060830152608082015260a00190565b60208082526022908201527f4669656c643a205472616e7366657220746f2f66726f6d20302061646472657360408201527f732e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526029908201527f4d61726b6574706c6163653a204c697374696e67206e6f74206f776e6564206260408201527f792073656e6465722e0000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d61726b6574706c6163653a20496e76616c69642070726963696e672066756e60408201527f6374696f6e2e0000000000000000000000000000000000000000000000000000606082015260800190565b60208082526015908201527f4d61726b6574706c6163653a20457870697265642e0000000000000000000000604082015260600190565b60208082526021908201527f4d61726b6574706c6163653a204c697374696e672068617320657870697265646040820152601760f91b606082015260800190565b6020808252818101527f4669656c643a20506f6420417070726f766520746f203020616464726573732e604082015260600190565b60208082526026908201527f42616c616e63653a20496e73756666696369656e7420696e7465726e616c206260408201527f616c616e63650000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f4669656c643a20506f642072616e676520696e76616c69642e00000000000000604082015260600190565b60208082526026908201527f4d61726b6574706c6163653a204f7264657220616d6f756e74206d757374206260408201527f65203e20302e0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f4d61726b6574706c6163653a20496e76616c696420506c6f742e000000000000604082015260600190565b6020808252602e908201527f4d61726b6574706c6163653a20506f64207072696365206d757374206265206760408201527f726561746572207468616e20302e000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4669656c643a20506c6f74206e6f74206f776e656420627920757365722e0000604082015260600190565b60208082526027908201527f4669656c643a2043616e6e6f74207472616e7366657220506f647320746f206f60408201527f6e6573656c662e00000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4d61726b6574706c6163653a2046696c6c206d757374206265203e3d206d696e60408201527f696d756d20616d6f756e742e0000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4d61726b6574706c6163653a204c697374696e6720646f6573206e6f7420657860408201527f6973742e00000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4d61726b6574706c6163653a20506c6f7420746f6f2066617220696e206c696e60408201527f652e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d61726b6574706c6163653a204e6f7420656e6f75676820706f647320696e2060408201527f4c697374696e672e000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526021908201527f4d61726b6574706c6163653a20496e76616c696420506c6f742f416d6f756e746040820152601760f91b606082015260800190565b60006101208c83528b60208401528a604084015262ffffff8a1660608401528860808401528760a08401528060c0840152613dbf81840187896134dc565b915050613dcb84613e78565b8360e0830152613dda83613e78565b826101008301529b9a5050505050505050505050565b60006101208b83528a602084015289604084015262ffffff891660608401528760808401528660a08401528060c0840152613e2d81840187613506565b915050613e3984613e78565b8360e0830152613e4883613e78565b826101008301529a9950505050505050505050565b93845260208401929092526040830152606082015260800190565b600281106103e657fefe4d61726b6574706c6163653a204e6f7420656e6f756768206265616e7320696e206f726465722e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774576616c756174696f6e206d7573742062652077697468696e2070696563657769736520626f756e64732e4576616c756174696f6e206d7573742062652077697468696e2070696563657769736520626f756e647353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235364d61726b6574706c6163653a204e6f7420656e6f75676820706f647320696e204c697374696e672e5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212202199b253731acaa9a9e10258ad8d8842c93a9f0c65c918a439c690c40afa31fe64736f6c63430007060033
Deployed Bytecode
0x60806040526004361061015f5760003560e01c8063845a022b116100c0578063c5644a6011610074578063df18a3ee11610059578063df18a3ee1461031a578063eda8156e1461032d578063f22b49ec146103405761015f565b8063c5644a60146102e7578063d6af17ab146102fa5761015f565b8063a99d840c116100a5578063a99d840c14610294578063b1719e59146102a7578063c3e14715146102c75761015f565b8063845a022b1461026e578063a8f135a2146102815761015f565b806369d9120d1161011757806380bd7d33116100fc57806380bd7d331461023557806382c6512414610248578063836019921461025b5761015f565b806369d9120d146102025780637e2a1fd1146102155761015f565b80630b385a85116101485780630b385a85146101ba5780633260c49e146101da5780634214861e146101ef5761015f565b8063042ff31d14610164578063045d57631461019a575b600080fd5b34801561017057600080fd5b5061018461017f366004612f76565b610353565b60405161019191906136e4565b60405180910390f35b3480156101a657600080fd5b506101846101b5366004612fe0565b61037e565b3480156101c657600080fd5b506101846101d5366004612ef8565b6103ab565b6101ed6101e8366004613046565b6103dc565b005b6101ed6101fd366004613129565b6103e9565b6101ed610210366004612f2a565b610401565b34801561022157600080fd5b506101846102303660046132ab565b61054a565b6101ed610243366004613406565b610579565b610184610256366004613268565b610588565b610184610269366004613398565b6105b5565b6101ed61027c3660046131ac565b6105e4565b6101ed61028f36600461345a565b6105f8565b6101ed6102a2366004613078565b610612565b3480156102b357600080fd5b506101846102c2366004613046565b610651565b3480156102d357600080fd5b506101846102e2366004613356565b610666565b6101ed6102f5366004612fb7565b6106d9565b34801561030657600080fd5b50610184610315366004613046565b610786565b6101ed61032836600461320b565b610798565b6101ed61033b3660046130ea565b6107aa565b6101ed61034e3660046132fc565b6107e7565b6000603781610364878787876107f4565b81526020019081526020016000205490505b949350505050565b6000603781610391888289898989610865565b815260200190815260200160002054905095945050505050565b6001600160a01b03808316600090815260316020908152604080832093851683526001909301905220545b92915050565b6103e633826108e2565b50565b6103f88787878787878761097a565b50505050505050565b601e546002141561042d5760405162461bcd60e51b815260040161042490613d09565b60405180910390fd5b6002601e556001600160a01b0385161580159061045257506001600160a01b03841615155b61046e5760405162461bcd60e51b8152600401610424906137b8565b6001600160a01b0385166000908152603160209081526040808320868452909152902054806104af5760405162461bcd60e51b815260040161042490613b01565b82821180156104be5750818110155b6104da5760405162461bcd60e51b8152600401610424906139d9565b50818103336001600160a01b0387161480159061050257506000196104ff87336103ab565b14155b1561051257610512863383610b83565b600084815260366020526040902054156105305761053086856108e2565b61053d8686868685610be5565b50506001601e5550505050565b600061056183838761055c8189610c9c565b610cfd565b905061057081620f4240610e1c565b95945050505050565b6103f887878787878787610e83565b600061059d610595610fae565b873385610fc6565b95506105ab8686868661114a565b9695505050505050565b60006105ca6105c2610fae565b883385610fc6565b96506105d98787878787611220565b979650505050505050565b6105f185858585856112d6565b5050505050565b61060888888888888888886114e8565b5050505050505050565b61064361061d610fae565b3361062b6020890189612ede565b878561063e6101008c0160e08d0161305e565b6115de565b93506105f1858585856116fd565b6000818152603760205260409020545b919050565b600080610674848489611878565b90508061068486620f42406118d2565b8161068b57fe5b04915060006106b583604051806060016040528060288152602001613f486028913989919061192b565b905081620f4240816106c357fe5b0481116106ce578692505b505095945050505050565b601e54600214156106fc5760405162461bcd60e51b815260040161042490613d09565b6002601e556001600160a01b0382166107275760405162461bcd60e51b815260040161042490613947565b6107323383836119c2565b816001600160a01b0316336001600160a01b03167f2602b28af334328fb380d7416219c5cd9c3c8a0cacda4fb8e090c56557477d488360405161077591906136e4565b60405180910390a350506001601e55565b60009081526036602052604090205490565b6107a4848484846119f2565b50505050565b6107d66107b5610fae565b336107c36020870187612ede565b858561063e6101008a0160e08b0161305e565b91506107e28383611a70565b505050565b6105f18585858585611bda565b6000811561083057848484846040516020016108139493929190613588565b604051602081830303815290604052805190602001209050610376565b84848460405160200161084593929190613551565b604051602081830303815290604052805190602001209050949350505050565b6000610887602061088160a861087b8787611c5c565b906118d2565b90610c9c565b82146108a55760405162461bcd60e51b815260040161042490613872565b8686868686866040516020016108c0969594939291906135c4565b6040516020818303038152906040528051906020012090509695505050505050565b6001600160a01b03821660009081526031602090815260408083208484529091529020546109225760405162461bcd60e51b815260040161042490613815565b60008181526036602052604080822091909155516001600160a01b038316907fe9dc43fcbeb08ecb743b537fa98567049e3b77e283833f89ab216b22ede6ba0a9061096e9084906136e4565b60405180910390a25050565b866060013584101561099e5760405162461bcd60e51b815260040161042490613b95565b6109a88585610c9c565b3360009081526031602090815260408083208a845290915290205410156109e15760405162461bcd60e51b815260040161042490613a6d565b600e54604088013590610a02906109fc876108818b8b610c9c565b90611c75565b1115610a205760405162461bcd60e51b815260040161042490613c4f565b6000610a45610a3260208a018a612ede565b60008a604001358b606001358888610865565b600e54909150600090610a6890610a60906109fc8b8b610c9c565b87878761054a565b9050610a9d81604051806060016040528060278152602001613e8360279139600085815260376020526040902054919061192b565b600083815260376020526040902055610abf610ab7610fae565b823386611cd2565b60008881526036602052604090205415610add57610add33896108e2565b610af633610aee60208c018c612ede565b8a8a8a610be5565b600082815260376020526040902054610b19576000828152603760205260408120555b610b2660208a018a612ede565b6001600160a01b0316336001600160a01b03167f525994627282299f72de05d7d3f543c6ec6c2022cb3898ad47ff18553c7655bf848b8b8b87604051610b70959493929190613795565b60405180910390a3505050505050505050565b6000610b8f84846103ab565b90506107a48484610be0856040518060400160405280601d81526020017f4669656c643a20496e73756666696369656e7420617070726f76616c2e0000008152508661192b9092919063ffffffff16565b6119c2565b836001600160a01b0316856001600160a01b03161415610c175760405162461bcd60e51b815260040161042490613b38565b610c2b84610c258585610c9c565b83611d14565b610c40858484610c3b8582610c9c565b611d3a565b610c4a8383610c9c565b846001600160a01b0316866001600160a01b03167fed4f3f107ad11834ddcfa24bee36362f72a9f0301995380177a0efb5b21c3d5984604051610c8d91906136e4565b60405180910390a45050505050565b600082820183811015610cf6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600080610d0a8686611c5c565b90506000610d1a87878785611dff565b90506000610d29888884611e76565b90506000610d3b898985600101611e76565b905060005b80610e0f5781871115610d5557506000610d59565b5060015b6000610d80846040518060600160405280602b8152602001613ecb602b91398b919061192b565b9050600082610d9857610d938486611c75565b610da2565b610da28986611c75565b9050610dbc610db58d8d898b8787611e99565b8990610c9c565b975082610e085783995060018703861415610dda5760019250610e08565b600190950194610deb8c8c88611e76565b9450600187038614610e0857610e058c8c88600101611e76565b93505b5050610d40565b5050505050949350505050565b6000808211610e72576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610e7b57fe5b049392505050565b3360009081526031602090815260408083208a8452909152902054610ea88787610c9c565b8110158015610eb75750600086115b610ed35760405162461bcd60e51b815260040161042490613d40565b60008562ffffff1611610ef85760405162461bcd60e51b815260040161042490613aa4565b600e54841015610f1a5760405162461bcd60e51b8152600401610424906138cf565b60008881526036602052604090205415610f3857610f3833896108e2565b610f46878787878787612002565b60008981526036602052604080822092909255905160609133917fb7653814153cbbed10e29f56c0ba102e97b4ce1078bbd8bd02da1ccce7d38fc991610f9b918d918d918d918d918d918d918b918e91613df0565b60405180910390a2505050505050505050565b73bea0000029ad1c77d3d5d23ba2d8893db9d1efab90565b600083610fd557506000610376565b6000826003811115610fe357fe5b14611028576110038386866001866003811115610ffc57fe5b1415612077565b90508084148061101e5750600382600381111561101c57fe5b145b1561102857610376565b6040516370a0823160e01b81526000906001600160a01b038716906370a08231906110579030906004016136d0565b60206040518083038186803b15801561106f57600080fd5b505afa158015611083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a79190613250565b90506110c06001600160a01b03871685308589036120de565b6105ab61114382886001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016110f391906136d0565b60206040518083038186803b15801561110b57600080fd5b505afa15801561111f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109fc9190613250565b8390610c9c565b600080851161116b5760405162461bcd60e51b815260040161042490613a10565b60008462ffffff16116111905760405162461bcd60e51b815260040161042490613aa4565b61119c338585856107f4565b600081815260376020526040902054909150156111c0576111c084848460016119f2565b6000818152603760205260408082208790555160609133917f7279c7b5d64f6bb98758727f0f16bcc5cf260997bfb49a45234c28fcb55fbcf09161120f9186918b918b918b918b918a91613742565b60405180910390a250949350505050565b60008086116112415760405162461bcd60e51b815260040161042490613a10565b61125033600087878787610865565b6000818152603760205260409020549091501561127557611275858585856001611bda565b6000818152603760205260408082208890555133917f7279c7b5d64f6bb98758727f0f16bcc5cf260997bfb49a45234c28fcb55fbcf0916112c59185918b91908b908b908b908b906001906136ed565b60405180910390a295945050505050565b84606001358210156112fa5760405162461bcd60e51b815260040161042490613b95565b6113048383610c9c565b336000908152603160209081526040808320888452909152902054101561133d5760405162461bcd60e51b815260040161042490613a6d565b600e54604086013590611358906109fc856108818989610c9c565b11156113765760405162461bcd60e51b815260040161042490613c4f565b60006113a76113886020880188612ede565b6113986040890160208a016131f1565b886040013589606001356107f4565b905060006113d7620f42406113d16113c560408b0160208c016131f1565b879062ffffff166118d2565b90610e1c565b905061140c81604051806060016040528060278152602001613e8360279139600085815260376020526040902054919061192b565b600083815260376020526040902055611426610ab7610fae565b600086815260366020526040902054156114445761144433876108e2565b61145d3361145560208a018a612ede565b888888610be5565b600082815260376020526040902054611480576000828152603760205260408120555b61148d6020880188612ede565b6001600160a01b0316336001600160a01b03167f525994627282299f72de05d7d3f543c6ec6c2022cb3898ad47ff18553c7655bf84898989876040516114d7959493929190613795565b60405180910390a350505050505050565b3360009081526031602090815260408083208b845290915290205461150d8888610c9c565b811015801561151c5750600087115b6115385760405162461bcd60e51b815260040161042490613d40565b600e5486101561155a5760405162461bcd60e51b8152600401610424906138cf565b6000898152603660205260409020541561157857611578338a6108e2565b611589888860008989898989612166565b60008a81526036602052604080822092909255905133917fb7653814153cbbed10e29f56c0ba102e97b4ce1078bbd8bd02da1ccce7d38fc991610f9b918d918d918d918d908d908d908d908d90600190613d81565b6000808360038111156115ed57fe5b1480156116055750600082600181111561160357fe5b145b156116d8576040516370a0823160e01b81526000906001600160a01b038916906370a08231906116399089906004016136d0565b60206040518083038186803b15801561165157600080fd5b505afa158015611665573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116899190613250565b90506116a06001600160a01b0389168888886120de565b6116d081896001600160a01b03166370a08231896040518263ffffffff1660e01b81526004016110f391906136d0565b9150506105ab565b6116e487858886610fc6565b93506116f287858785611cd2565b509195945050505050565b600061173e6040860135606087013561171c60a0890160808a016131f1565b60a089013560c08a013588886117396101008e0160e08f0161305e565b612166565b60208087013560009081526036909152604090205490915081146117745760405162461bcd60e51b815260040161042490613bf2565b60006031816117866020890189612ede565b6001600160a01b0316815260208082019290925260409081016000908120898401358252909252908190205491506117c5908701356060880135610c9c565b81101580156117d8575060008660600135115b6117f45760405162461bcd60e51b815260040161042490613d40565b600e5460a0870135101561181a5760405162461bcd60e51b815260040161042490613906565b600e546000906118479061183a906109fc60208b013560408c0135610c9c565b8860600135888888610666565b905061185733888787858b6121eb565b6103f86118676020890189612ede565b3389602001358a6040013585610be5565b6000806118858585611c5c565b9050600061189586868685611dff565b90506105ab868683856118cd6118ac8c8c89611e76565b6040518060600160405280602a8152602001613ef6602a91398b919061192b565b61232d565b6000826118e1575060006103d6565b828202828482816118ee57fe5b0414610cf65760405162461bcd60e51b8152600401808060200182810382526021815260200180613eaa6021913960400191505060405180910390fd5b600081848411156119ba5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561197f578181015183820152602001611967565b50505050905090810190601f1680156119ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b039283166000908152603160209081526040808320949095168252600190930190925291902055565b6000611a00338686866107f4565b600081815260376020526040902054909150611a1d610ab7610fae565b600082815260376020526040808220919091555133907f531180eb4d1153cb99f00e54fef0a473edc9e3e951f9a88468fec65988e9e4f890611a609085906136e4565b60405180910390a2505050505050565b6000611aaf60408401356060850135611a8f60a08701608088016131f1565b60a087013560c0880135611aaa6101008a0160e08b0161305e565b612002565b6020808501356000908152603690915260409020549091508114611ae55760405162461bcd60e51b815260040161042490613bf2565b6000603181611af76020870187612ede565b6001600160a01b031681526020808201929092526040908101600090812087840135825290925290819020549150611b36908501356060860135610c9c565b8110158015611b49575060008460600135115b611b655760405162461bcd60e51b815260040161042490613d40565b600e5460a08501351015611b8b5760405162461bcd60e51b815260040161042490613906565b6000611bab611ba060a08701608088016131f1565b8660600135866123fa565b9050611bb933868387612464565b6105f1611bc96020870187612ede565b338760200135886040013585610be5565b6000611beb33600088888888610865565b600081815260376020526040902054909150611c08610ab7610fae565b600082815260376020526040808220919091555133907f531180eb4d1153cb99f00e54fef0a473edc9e3e951f9a88468fec65988e9e4f890611c4b9085906136e4565b60405180910390a250505050505050565b6000610cf681611c6f8585836020612587565b90612640565b600082821115611ccc576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b82611cdc576107a4565b6001816001811115611cea57fe5b1415611d0057611cfb8285856126fc565b6107a4565b6107a46001600160a01b038516838561272c565b6001600160a01b0390921660009081526031602090815260408083209383529290522055565b6001600160a01b038416600090815260316020908152604080832086845290915290205482611d8c576001600160a01b0385166000908152603160209081526040808320878452909152812055611db3565b6001600160a01b038516600090815260316020908152604080832087845290915290208390555b8082146105f157611dc48183611c75565b6001600160a01b038616600090815260316020526040812090611de78786610c9c565b81526020810191909152604001600020555050505050565b600080611e0e86866000611e76565b905080841015611e22576000915050610376565b60005b83811015611e685784821415611e3e5791506103769050565b84821115611e53576000190191506103769050565b600101611e61878783611e76565b9150611e25565b600019019695505050505050565b600061037681611c6f611e8e602061088187826118d2565b879087906020612587565b600080600080611eab8a8a8a8a6127ac565b90506000611ebb8b8b8b8b612829565b90506000611ecb8c8c8c8c6128b3565b905060005b60038111611fe757818160048110611ee457fe5b602002015115611f9057611f41611f3a611f198360010161087b600a888760048110611f0c57fe5b602002015160ff1661297e565b6113d1878560048110611f2857fe5b602002015161087b8d8760010161297e565b8790610c9c565b9550611f89611f82611f618360010161087b600a888760048110611f0c57fe5b6113d1878560048110611f7057fe5b602002015161087b8e8760010161297e565b8790611c75565b9550611fdf565b611fb5611fae611f198360010161087b600a888760048110611f0c57fe5b8690610c9c565b9450611fdc611fd5611f618360010161087b600a888760048110611f0c57fe5b8690611c75565b94505b600101611ed0565b50611ff28585611c75565b9c9b505050505050505050505050565b60008215612050578686868686600087600181111561201d57fe5b1460405160200161203396959493929190613647565b6040516020818303038152906040528051906020012090506105ab565b86868686600086600181111561206257fe5b146040516020016108c0959493929190613612565b60008061208486866129df565b905082806120925750838110155b6120ae5760405162461bcd60e51b81526004016104249061397c565b6120b88185612a1b565b91508181036120d48787836120cc87612a31565b600003612a95565b5050949350505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526107a4908590612b10565b600061217c602061088160a861087b8888611c5c565b831461219a5760405162461bcd60e51b815260040161042490613872565b888888888860008760018111156121ad57fe5b1489896040516020016121c7989796959493929190613681565b60405160208183030381529060405280519060200120905098975050505050505050565b8460c0013582101561220f5760405162461bcd60e51b815260040161042490613b95565b81856060013510156122335760405162461bcd60e51b815260040161042490613cac565b60208086013560009081526036909152604081205560608501358210156122c0576122946000612267606088013585611c75565b61227760a0890160808a016131f1565b60a089013560c08a013589896117396101008e0160e08f0161305e565b603660006122ae604089013561088160208b013588610c9c565b81526020810191909152604001600020555b6001600160a01b0386166122d76020870187612ede565b6001600160a01b03167fb33a5c3dd7c4265e5702ad84b5c4f6bb3971d2424a47955979a642fe9d77f4c387602001358860400135868660405161231d9493929190613e5d565b60405180910390a3505050505050565b60008060008061233f898989896127ac565b9050600061234f8a8a8a8a612829565b9050600061235f8b8b8b8b6128b3565b905060005b600381116123e05781816004811061237857fe5b6020020151156123be576123b7611f3a612399600a868560048110611f0c57fe5b6113d18785600481106123a857fe5b602002015161087b8d8761297e565b95506123d8565b6123d5611fae612399600a868560048110611f0c57fe5b94505b600101612364565b506123eb8585611c75565b9b9a5050505050505050505050565b60008362ffffff1682620f4240028161240f57fe5b049050600061243982604051806060016040528060288152602001613f486028913986919061192b565b90508462ffffff16620f42408161244c57fe5b0462ffffff16811161245c578391505b509392505050565b8260c001358210156124885760405162461bcd60e51b815260040161042490613b95565b81836060013510156124ac5760405162461bcd60e51b815260040161042490613cac565b602080840135600090815260369091526040812055606083013582101561251c576124f060006124e0606086013585611c75565b611a8f60a08701608088016131f1565b6036600061250a6040870135610881602089013588610c9c565b81526020810191909152604001600020555b6001600160a01b0384166125336020850185612ede565b6001600160a01b03167fb33a5c3dd7c4265e5702ad84b5c4f6bb3971d2424a47955979a642fe9d77f4c38560200135866040013586866040516125799493929190613e5d565b60405180910390a350505050565b606060008267ffffffffffffffff811180156125a257600080fd5b506040519080825280601f01601f1916602001820160405280156125cd576020820181803683370190505b50905060005b838110156126365786868287018181106125e957fe5b9050013560f81c60f81b8282815181106125ff57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001016125d3565b5095945050505050565b60008182602001101561269a576040805162461bcd60e51b815260206004820152601260248201527f746f55696e743235365f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b81602001835110156126f3576040805162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b50016020015190565b600061270884846129df565b905060006127168284610c9c565b90506105f185858361272787612a31565b612a95565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107e2908490612b10565b6127b4612e08565b60006127e16127d660206108816127cb87836118d2565b6108818960806118d2565b879087906080612587565b90506127ee816000612640565b82526127fb816020612640565b602083015261280b816040612640565b604083015261281b816060612640565b606083015250949350505050565b612831612e08565b600061285f61285460206108816128498760a06118d2565b6108818960046118d2565b879087906004612587565b905061286c816000612bc1565b60ff16825261287c816001612bc1565b60ff16602083015261288f816002612bc1565b60ff1660408301526128a2816003612bc1565b60ff16606083015250949350505050565b6128bb612e08565b60006128d361285460206108816128498760a46118d2565b90506128e0816000612bc1565b60ff16600114826000600481106128f357fe5b91151560209092020152612908816001612bc1565b60ff166001148260016004811061291b57fe5b91151560209092020152612930816002612bc1565b60ff166001148260026004811061294357fe5b91151560209092020152612958816003612bc1565b60ff166001148260036004811061296b57fe5b9115156020909202015250949350505050565b60008161298d575060016103d6565b816001141561299d5750816103d6565b821580156129aa57508115155b156129b7575060006103d6565b8260015b838110156129d7576129cd82866118d2565b91506001016129bb565b5090506103d6565b6000806129ea612c7d565b6001600160a01b039485166000908152603e9190910160209081526040808320959096168252939093525050205490565b6000818310612a2a5781610cf6565b5090919050565b60007f80000000000000000000000000000000000000000000000000000000000000008210612a915760405162461bcd60e51b8152600401808060200182810382526028815260200180613f206028913960400191505060405180910390fd5b5090565b6000612a9f612c7d565b6001600160a01b038087166000818152603e840160209081526040808320948a1680845294909152908190208790555192935090917f18e1ea4139e68413d7d08aa752e71568e36b2c5bf940893314c2c5b01eaa0c4290612b019086906136e4565b60405180910390a35050505050565b6000612b65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612c829092919063ffffffff16565b8051909150156107e257808060200190516020811015612b8457600080fd5b50516107e25760405162461bcd60e51b815260040180806020018281038252602a815260200180613f70602a913960400191505060405180910390fd5b600081826001011015612c1b576040805162461bcd60e51b815260206004820152601060248201527f746f55696e74385f6f766572666c6f7700000000000000000000000000000000604482015290519081900360640190fd5b8160010183511015612c74576040805162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e647300000000000000000000000000604482015290519081900360640190fd5b50016001015190565b600090565b6060610376848460008585612c9685612d9c565b612ce7576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310612d255780518252601f199092019160209182019101612d06565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612d87576040519150601f19603f3d011682016040523d82523d6000602084013e612d8c565b606091505b50915091506105d9828286612da2565b3b151590565b60608315612db1575081610cf6565b825115612dc15782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561197f578181015183820152602001611967565b60405180608001604052806004906020820280368337509192915050565b80356001600160a01b038116811461066157600080fd5b60008083601f840112612e4e578182fd5b50813567ffffffffffffffff811115612e65578182fd5b602083019150836020828501011115612e7d57600080fd5b9250929050565b80356004811061066157600080fd5b80356002811061066157600080fd5b60006101008284031215612eb4578081fd5b50919050565b600060808284031215612eb4578081fd5b803562ffffff8116811461066157600080fd5b600060208284031215612eef578081fd5b610cf682612e26565b60008060408385031215612f0a578081fd5b612f1383612e26565b9150612f2160208401612e26565b90509250929050565b600080600080600060a08688031215612f41578081fd5b612f4a86612e26565b9450612f5860208701612e26565b94979496505050506040830135926060810135926080909101359150565b60008060008060808587031215612f8b578384fd5b612f9485612e26565b9350612fa260208601612ecb565b93969395505050506040820135916060013590565b60008060408385031215612fc9578182fd5b612fd283612e26565b946020939093013593505050565b600080600080600060808688031215612ff7578081fd5b61300086612e26565b94506020860135935060408601359250606086013567ffffffffffffffff811115613029578182fd5b61303588828901612e3d565b969995985093965092949392505050565b600060208284031215613057578081fd5b5035919050565b60006020828403121561306f578081fd5b610cf682612e93565b60008060008060006101608688031215613090578081fd5b61309a8787612ea2565b9450610100860135935061012086013567ffffffffffffffff8111156130be578182fd5b6130ca88828901612e3d565b90945092506130de90506101408701612e84565b90509295509295909350565b600080600061014084860312156130ff578283fd5b6131098585612ea2565b925061010084013591506131206101208501612e84565b90509250925092565b6000806000806000806000610120888a031215613144578485fd5b61314e8989612eba565b96506080880135955060a0880135945060c0880135935060e088013567ffffffffffffffff81111561317e578283fd5b61318a8a828b01612e3d565b909450925061319e90506101008901612e93565b905092959891949750929550565b600080600080600061010086880312156131c4578283fd5b6131ce8787612eba565b94506080860135935060a0860135925060c086013591506130de60e08701612e93565b600060208284031215613202578081fd5b610cf682612ecb565b60008060008060808587031215613220578182fd5b61322985612ecb565b9350602085013592506040850135915061324560608601612e93565b905092959194509250565b600060208284031215613261578081fd5b5051919050565b600080600080600060a0868803121561327f578283fd5b8535945061328f60208701612ecb565b935060408601359250606086013591506130de60808701612e84565b600080600080606085870312156132c0578182fd5b8435935060208501359250604085013567ffffffffffffffff8111156132e4578283fd5b6132f087828801612e3d565b95989497509550505050565b600080600080600060808688031215613313578283fd5b8535945060208601359350604086013567ffffffffffffffff811115613337578384fd5b61334388828901612e3d565b90945092506130de905060608701612e93565b60008060008060006080868803121561336d578283fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613029578182fd5b60008060008060008060a087890312156133b0578384fd5b863595506020870135945060408701359350606087013567ffffffffffffffff8111156133db578283fd5b6133e789828a01612e3d565b90945092506133fa905060808801612e84565b90509295509295509295565b600080600080600080600060e0888a031215613420578081fd5b87359650602088013595506040880135945061343e60608901612ecb565b93506080880135925060a0880135915061319e60c08901612e93565b60008060008060008060008060e0898b031215613475578182fd5b883597506020890135965060408901359550606089013594506080890135935060a089013567ffffffffffffffff8111156134ae578283fd5b6134ba8b828c01612e3d565b90945092506134cd905060c08a01612e93565b90509295985092959890939650565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452815b8181101561352b5760208185018101518683018201520161350f565b8181111561353c5782602083870101525b50601f01601f19169290920160200192915050565b60609390931b6bffffffffffffffffffffffff1916835260e89190911b6001600160e81b0319166014830152601782015260370190565b60609490941b6bffffffffffffffffffffffff1916845260e89290921b6001600160e81b03191660148401526017830152603782015260570190565b60006bffffffffffffffffffffffff198860601b1682526001600160e81b03198760e81b16601483015285601783015284603783015282846057840137910160570190815295945050505050565b948552602085019390935260e89190911b6001600160e81b03191660408401526043830152151560f81b606382015260640190565b958652602086019490945260e89290921b6001600160e81b031916604085015260438401526063830152151560f81b608382015260840190565b60008982528860208301526001600160e81b03198860e81b16604083015286604383015285606383015284151560f81b6083830152828460848401379101608401908152979650505050505050565b6001600160a01b0391909116815260200190565b90815260200190565b600089825288602083015262ffffff8816604083015286606083015285608083015260e060a083015261372460e0830185876134dc565b905061372f83613e78565b8260c08301529998505050505050505050565b600088825287602083015262ffffff8716604083015285606083015284608083015260e060a083015261377860e0830185613506565b905061378383613e78565b8260c083015298975050505050505050565b948552602085019390935260408401919091526060830152608082015260a00190565b60208082526022908201527f4669656c643a205472616e7366657220746f2f66726f6d20302061646472657360408201527f732e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526029908201527f4d61726b6574706c6163653a204c697374696e67206e6f74206f776e6564206260408201527f792073656e6465722e0000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d61726b6574706c6163653a20496e76616c69642070726963696e672066756e60408201527f6374696f6e2e0000000000000000000000000000000000000000000000000000606082015260800190565b60208082526015908201527f4d61726b6574706c6163653a20457870697265642e0000000000000000000000604082015260600190565b60208082526021908201527f4d61726b6574706c6163653a204c697374696e672068617320657870697265646040820152601760f91b606082015260800190565b6020808252818101527f4669656c643a20506f6420417070726f766520746f203020616464726573732e604082015260600190565b60208082526026908201527f42616c616e63653a20496e73756666696369656e7420696e7465726e616c206260408201527f616c616e63650000000000000000000000000000000000000000000000000000606082015260800190565b60208082526019908201527f4669656c643a20506f642072616e676520696e76616c69642e00000000000000604082015260600190565b60208082526026908201527f4d61726b6574706c6163653a204f7264657220616d6f756e74206d757374206260408201527f65203e20302e0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f4d61726b6574706c6163653a20496e76616c696420506c6f742e000000000000604082015260600190565b6020808252602e908201527f4d61726b6574706c6163653a20506f64207072696365206d757374206265206760408201527f726561746572207468616e20302e000000000000000000000000000000000000606082015260800190565b6020808252601e908201527f4669656c643a20506c6f74206e6f74206f776e656420627920757365722e0000604082015260600190565b60208082526027908201527f4669656c643a2043616e6e6f74207472616e7366657220506f647320746f206f60408201527f6e6573656c662e00000000000000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f4d61726b6574706c6163653a2046696c6c206d757374206265203e3d206d696e60408201527f696d756d20616d6f756e742e0000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f4d61726b6574706c6163653a204c697374696e6720646f6573206e6f7420657860408201527f6973742e00000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526022908201527f4d61726b6574706c6163653a20506c6f7420746f6f2066617220696e206c696e60408201527f652e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d61726b6574706c6163653a204e6f7420656e6f75676820706f647320696e2060408201527f4c697374696e672e000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60208082526021908201527f4d61726b6574706c6163653a20496e76616c696420506c6f742f416d6f756e746040820152601760f91b606082015260800190565b60006101208c83528b60208401528a604084015262ffffff8a1660608401528860808401528760a08401528060c0840152613dbf81840187896134dc565b915050613dcb84613e78565b8360e0830152613dda83613e78565b826101008301529b9a5050505050505050505050565b60006101208b83528a602084015289604084015262ffffff891660608401528760808401528660a08401528060c0840152613e2d81840187613506565b915050613e3984613e78565b8360e0830152613e4883613e78565b826101008301529a9950505050505050505050565b93845260208401929092526040830152606082015260800190565b600281106103e657fefe4d61726b6574706c6163653a204e6f7420656e6f756768206265616e7320696e206f726465722e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774576616c756174696f6e206d7573742062652077697468696e2070696563657769736520626f756e64732e4576616c756174696f6e206d7573742062652077697468696e2070696563657769736520626f756e647353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235364d61726b6574706c6163653a204e6f7420656e6f75676820706f647320696e204c697374696e672e5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212202199b253731acaa9a9e10258ad8d8842c93a9f0c65c918a439c690c40afa31fe64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.