Contract
0x396dd1f7E3c8044784937935F834C3F8d58EB497
2
Contract Overview
Balance:
0.9738 ETH
ETH Value:
$1,534.75 (@ $1,576.04/ETH)
My Name Tag:
Not Available
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
BountyAuction
Compiler Version
v0.8.0+commit.c7dfd78e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.0; import "./PricingSession.sol"; import "./ABCTreasury.sol"; import "./helpers/ReentrancyGuard.sol"; ///@author Medici ///@title Bounty auction contract for Abacus contract BountyAuction is ReentrancyGuard { /// @notice store pricing session address PricingSession public session; /// @notice store treasury address ABCTreasury public treasury; /* ======== ADDRESS ======== */ /// @notice store contract admin address address public admin; /// @notice store ABC token contract address public ABCToken; /* ======== BOOL ======== */ /// @notice track auction active status bool public auctionStatus; /// @notice used for customizable first session timeline bool public firstSession; /* ======== UINT ======== */ /// @notice used to map to current bounty auction uint public nonce; /* ======== MAPPINGS ======== */ /*////////////////////////////// // PER AUCTION STORAGE // //////////////////////////////*/ /// @notice maps the auction nonce to it's highest bid value mapping(uint => uint) public highestBid; /// @notice maps the auction nonce to it's highest bidder mapping(uint => address) public highestBidder; /// @notice maps the auction nonce to it's end timestamp mapping(uint => uint) public endTime; /// @notice maps the auction nonce to it's winner mapping(uint => address) public winners; /// @notice maps the action to all it's votes mapped to the voter mapping(uint => mapping(address => AuctionVote)) public userVote; /*////////////////////////////// // PER ACCOUNT STORAGE // //////////////////////////////*/ mapping(address => uint) bidTime; mapping(address => uint) tvl; /* ======== STRUCTS ======== */ /// @notice stores bidders core information struct AuctionVote { address nftAddress; uint tokenid; uint intitialAppraisal; uint bid; } /* ======== EVENTS ======== */ event newBidSubmitted(address _bidder, uint _bidAmount, address _nftAddress, uint _tokenid, uint _initialAppraisal); event auctionEnded(address _highestBidder, uint _highestBid, address _nftAddress, uint _tokenid, uint _initialAppraisal); /* ======== Constructor ======== */ constructor() { /// @notice set contract admin admin = msg.sender; /// @notice set session account status to signify auction is active auctionStatus = true; } /* ======== ADMIN ======== */ ///@notice toggles active status of Auction contract function toggleAuction() external { require(msg.sender == admin); auctionStatus = !auctionStatus; nonce++; } /// @notice set session contract to be stored /// @param _session address of desired Pricing Session principle contract function setSessionContract(address _session) external { require(msg.sender == admin); session = PricingSession(payable(_session)); } /// @notice set treasury contract to be stored /// @param _treasury address of desired ABC treasury address function setTreasury(address _treasury) external { require(msg.sender == admin); treasury = ABCTreasury(payable(_treasury)); } /// @notice set token contract to be stored /// @param _token address of desired ABC token contract function setToken(address _token) external { require(msg.sender == admin); ABCToken = _token; } /// @notice change the state of first session once first auction is complete /// @param _state bool representative of whether or not we're currently in the first session function setFirst(bool _state) external { require(msg.sender == admin); firstSession = _state; } /* ======== AUCTION INTERACTION ======== */ /// @notice allow user to submit new bid /// @param _nftAddress - address of the ERC721/ERC1155 token /// @param _tokenid - ID of the token /// @param _initialAppraisal - initial nft appraisal function newBid(address _nftAddress, uint _tokenid, uint _initialAppraisal) nonReentrant payable external { require( msg.value > highestBid[nonce] && auctionStatus && (session.nftNonce(_nftAddress,_tokenid) == 0 || session.getStatus(_nftAddress, _tokenid) == 5) ); bidTime[msg.sender] = block.timestamp; highestBidder[nonce] = msg.sender; highestBid[nonce] = msg.value; tvl[msg.sender] -= userVote[nonce][msg.sender].bid; (bool sent, ) = payable(msg.sender).call{value: userVote[nonce][msg.sender].bid}(""); require(sent); userVote[nonce][msg.sender].nftAddress = _nftAddress; userVote[nonce][msg.sender].tokenid = _tokenid; userVote[nonce][msg.sender].intitialAppraisal = _initialAppraisal; userVote[nonce][msg.sender].bid = msg.value; tvl[msg.sender] += msg.value; emit newBidSubmitted(msg.sender, msg.value, _nftAddress, _tokenid, _initialAppraisal); } /// @notice allow add to past bid /// @param _nftAddress - address of the ERC721/ERC1155 token /// @param _tokenid - ID of the token function addToBid(address _nftAddress, uint _tokenid) nonReentrant payable external { require( userVote[nonce][msg.sender].bid + msg.value > highestBid[nonce] && auctionStatus && (session.nftNonce(_nftAddress,_tokenid) == 0 || session.getStatus(_nftAddress, _tokenid) == 5) ); userVote[nonce][msg.sender].bid += msg.value; highestBidder[nonce] = msg.sender; highestBid[nonce] = userVote[nonce][msg.sender].bid; tvl[msg.sender] += msg.value; } /// @notice allow user to change nft that they'd like appraised if they win /// @param _nftAddress users desired NFT address for session to be created /// @param _tokenid users desired tokenid for session to be created /// @param _initialAppraisal users desired initial appraisal value for session to be created function changeInfo(address _nftAddress, uint _tokenid, uint _initialAppraisal) external { require(userVote[nonce][msg.sender].nftAddress != address(0) && auctionStatus); userVote[nonce][msg.sender].nftAddress = _nftAddress; userVote[nonce][msg.sender].tokenid = _tokenid; userVote[nonce][msg.sender].intitialAppraisal = _initialAppraisal; } /// @notice triggered when auction ends, starts session for highest bidder function endAuction() nonReentrant external { if(firstSession) { require(msg.sender == admin); } require(endTime[nonce] < block.timestamp && auctionStatus); uint bountySend = userVote[nonce][highestBidder[nonce]].bid; tvl[highestBidder[nonce]] -= bountySend; session.createNewSession{value: bountySend}( userVote[nonce][highestBidder[nonce]].nftAddress, userVote[nonce][highestBidder[nonce]].tokenid, userVote[nonce][highestBidder[nonce]].intitialAppraisal, 86400 ); userVote[nonce][highestBidder[nonce]].bid = 0; endTime[++nonce] = block.timestamp + 86400; emit auctionEnded( highestBidder[nonce], userVote[nonce][highestBidder[nonce]].bid, userVote[nonce][highestBidder[nonce]].nftAddress, userVote[nonce][highestBidder[nonce]].tokenid, userVote[nonce][highestBidder[nonce]].intitialAppraisal ); } /// @notice allows users to claim non-employed funds function claim() nonReentrant external { uint returnValue; if(highestBidder[nonce] != msg.sender) { returnValue = tvl[msg.sender]; userVote[nonce][msg.sender].bid = 0; } else { returnValue = tvl[msg.sender] - userVote[nonce][msg.sender].bid; } tvl[msg.sender] -= returnValue; (bool sent, ) = payable(msg.sender).call{value: returnValue}(""); require(sent); } }
pragma solidity ^0.8.0; import "./helpers/ReentrancyGuard.sol"; import "./interfaces/IABCTreasury.sol"; import "./libraries/SafeMath.sol"; import "./libraries/sqrtLibrary.sol"; import "./libraries/PostSessionLibrary.sol"; import "./interfaces/IERC20.sol"; import "./ABCTreasury.sol"; /// @author Medici /// @title Pricing session contract for Abacus contract PricingSession is ReentrancyGuard { using SafeMath for uint; /* ======== ADDRESS ======== */ address public ABCToken; ABCTreasury public Treasury; address public admin; address auction; /* ======== BOOL ======== */ bool auctionStatus; bool tokenStatus; /* ======== MAPPINGS ======== */ /// @notice maps each user to their total points earned mapping(address => uint) public points; /// @notice maps each user to their total profit earned mapping(address => uint) public profitStored; /// @notice maps each user to their principal stored mapping(address => uint) public principalStored; /// @notice maps each NFT to its current nonce value mapping(address => mapping (uint => uint)) public nftNonce; mapping(uint => mapping(address => mapping(uint => VotingSessionMapping))) NftSessionMap; /// @notice maps each NFT pricing session (nonce dependent) to its necessary session checks (i.e. checking session progression) /// @dev nonce => tokenAddress => tokenId => session metadata mapping(uint => mapping(address => mapping(uint => VotingSessionChecks))) public NftSessionCheck; /// @notice maps each NFT pricing session (nonce dependent) to its necessary session core values (i.e. total participants, total stake, etc...) mapping(uint => mapping(address => mapping(uint => VotingSessionCore))) public NftSessionCore; /// @notice maps each NFT pricing session (nonce dependent) to its final appraisal value output mapping(uint => mapping(address => mapping(uint => uint))) public finalAppraisalValue; /* ======== STRUCTS ======== */ /// @notice tracks all of the mappings necessary to operate a session struct VotingSessionMapping { mapping (address => uint) voterCheck; mapping (address => uint) winnerPoints; mapping (address => uint) amountHarvested; mapping (address => Voter) nftVotes; } /// @notice track necessary session checks (i.e. whether its time to weigh votes or harvest) struct VotingSessionChecks { uint sessionProgression; uint calls; uint correct; uint incorrect; uint timeFinalAppraisalSet; } /// @notice track the core values of a session (max appraisal value, total session stake, etc...) struct VotingSessionCore { uint endTime; uint bounty; uint lowestStake; uint maxAppraisal; uint totalAppraisalValue; uint totalSessionStake; uint totalProfit; uint totalWinnerPoints; uint totalVotes; uint uniqueVoters; uint votingTime; } /// @notice track voter information struct Voter { bytes32 concealedAppraisal; uint base; uint appraisal; uint stake; } /* ======== EVENTS ======== */ event PricingSessionCreated(address creator_, uint nonce, address nftAddress_, uint tokenid_, uint initialAppraisal_, uint bounty_); event newAppraisalAdded(address voter_, uint nonce, address nftAddress_, uint tokenid_, uint stake_, bytes32 userHash_); event bountyIncreased(address sender_, uint nonce, address nftAddress_, uint tokenid_, uint amount_); event appraisalIncreased(address sender_, uint nonce, address nftAddress_, uint tokenid_, uint amount_); event voteWeighed(address user_, uint nonce, address nftAddress_, uint tokenid_, uint appraisal); event finalAppraisalDetermined(uint nonce, address nftAddress_, uint tokenid_, uint finalAppraisal, uint amountOfParticipants, uint totalStake); event userHarvested(address user_, uint nonce, address nftAddress_, uint tokenid_, uint harvested); event ethClaimedByUser(address user_, uint ethClaimed); event ethToABCExchange(address user_, uint ethExchanged, uint ppSent); event sessionEnded(address nftAddress, uint tokenid, uint nonce); /* ======== CONSTRUCTOR ======== */ constructor(address _treasury, address _auction) { Treasury = ABCTreasury(payable(_treasury)); auction = _auction; admin = msg.sender; auctionStatus = true; tokenStatus = false; } /// @notice set the auction address to be referenced throughout the contract /// @param _auction desired auction address to be stored and referenced in contract function setAuction(address _auction) external { require(msg.sender == admin); auction = _auction; } /// @notice set the auction status based on the active/inactive status of the bounty auction /// @param status desired auction status to be stored and referenced in contract function setAuctionStatus(bool status) external { require(msg.sender == admin); auctionStatus = status; } function setABCToken(address _token) external { ABCToken = _token; tokenStatus = true; } /// @notice Allow user to create new session and attach initial bounty /** @dev NFT sessions are indexed using a nonce per specific nft. The mapping is done by mapping a nonce to an NFT address to the NFT token id. */ /// @param nftAddress NFT contract address of desired NFT to be priced /// @param tokenid NFT token id of desired NFT to be priced /// @param _initialAppraisal appraisal value for max value to be instantiated against /// @param _votingTime voting window duration function createNewSession( address nftAddress, uint tokenid, uint _initialAppraisal, uint _votingTime ) stopOverwrite(nftAddress, tokenid) external payable { require(_votingTime <= 1 days && (!auctionStatus || msg.sender == auction)); VotingSessionCore storage sessionCore = NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid]; if(msg.sender == auction) {} else { uint abcCost = 0.005 ether *(ethToAbc()); (bool abcSent) = IERC20(ABCToken).transferFrom(msg.sender, address(Treasury), abcCost); require(abcSent); } if(nftNonce[nftAddress][tokenid] == 0 || getStatus(nftAddress, tokenid) == 5) {} else if(block.timestamp > sessionCore.endTime + sessionCore.votingTime * 3) { _executeEnd(nftAddress, tokenid); } nftNonce[nftAddress][tokenid]++; VotingSessionCore storage sessionCoreNew = NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid]; sessionCoreNew.votingTime = _votingTime; sessionCoreNew.maxAppraisal = 69420 * _initialAppraisal / 1000; sessionCoreNew.lowestStake = 100000 ether; sessionCoreNew.endTime = block.timestamp + _votingTime; sessionCoreNew.bounty = msg.value; emit PricingSessionCreated(msg.sender, nftNonce[nftAddress][tokenid], nftAddress, tokenid, _initialAppraisal, msg.value); } function depositPrincipal() nonReentrant payable external { principalStored[msg.sender] += msg.value; } /// @notice allows user to reclaim principalUsed in batches function claimPrincipalUsed(uint _amount) nonReentrant external { require(_amount <= principalStored[msg.sender]); principalStored[msg.sender] -= _amount; (bool sent, ) = msg.sender.call{value: _amount}(""); require(sent); } /// @notice allows user to claim batched earnings /// @param trigger denotes whether the user desires it in ETH (1) or ABC (2) function claimProfitsEarned(uint trigger, uint _amount) nonReentrant external { require(trigger == 1 || trigger == 2); if(trigger == 2) { require(tokenStatus); } require(profitStored[msg.sender] >= _amount); if(trigger == 1) { (bool sent1, ) = msg.sender.call{value: _amount}(""); require(sent1); profitStored[msg.sender] -= _amount; emit ethClaimedByUser(msg.sender, _amount); } else if(trigger == 2) { uint abcAmount = _amount / (0.00005 ether + 0.000015 ether * Treasury.tokensClaimed()/(1000000*1e18)); uint abcPayout = ((_amount / (0.00005 ether + 0.000015 ether * Treasury.tokensClaimed()/(1000000*1e18))) + (_amount / (0.00005 ether + 0.000015 ether * Treasury.tokensClaimed() + abcAmount) / (1000000*1e18)) / 2); (bool sent3, ) = payable(Treasury).call{value: _amount}(""); require(sent3); profitStored[msg.sender] -= _amount; Treasury.sendABCToken(msg.sender, abcPayout * 1e18); emit ethToABCExchange(msg.sender, _amount, abcPayout); } } /* ======== USER VOTE FUNCTIONS ======== */ /// @notice Allows user to set vote in party /** @dev Users appraisal is hashed so users can't track final appraisal and submit vote right before session ends. Therefore, users must remember their appraisal in order to reveal their appraisal in the next function. */ /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised /// @param concealedAppraisal concealed bid that is a hash of the appraisooooors appraisal value, wallet address, and seed number function setVote( address nftAddress, uint tokenid, uint stake, bytes32 concealedAppraisal ) properVote(nftAddress, tokenid, stake) external { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; require(sessionCore.endTime > block.timestamp && stake <= principalStored[msg.sender]); sessionMap.voterCheck[msg.sender] = 1; principalStored[msg.sender] -= stake; if (stake < sessionCore.lowestStake) { sessionCore.lowestStake = stake; } sessionCore.uniqueVoters++; sessionCore.totalSessionStake = sessionCore.totalSessionStake.add(stake); sessionMap.nftVotes[msg.sender].concealedAppraisal = concealedAppraisal; sessionMap.nftVotes[msg.sender].stake = stake; emit newAppraisalAdded(msg.sender, nonce, nftAddress, tokenid, stake, concealedAppraisal); } /// @notice allow user to update value inputs of their vote while voting is still active /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised /// @param concealedAppraisal concealed bid that is a hash of the appraisooooors new appraisal value, wallet address, and seed number function updateVote( address nftAddress, uint tokenid, bytes32 concealedAppraisal ) external { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; require(sessionMap.voterCheck[msg.sender] == 1); require(sessionCore.endTime > block.timestamp); sessionMap.nftVotes[msg.sender].concealedAppraisal = concealedAppraisal; } /// @notice Reveals user vote and weights based on the sessions lowest stake /** @dev calculation can be found in the weightVoteLibrary.sol file. Votes are weighted as sqrt(userStake/lowestStake). Depending on a votes weight it is then added as multiple votes of that appraisal (i.e. if someoneone has voting weight of 8, 8 votes are submitted using their appraisal). */ /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised /// @param appraisal appraisooooor appraisal value used to unlock concealed appraisal /// @param seedNum appraisooooor seed number used to unlock concealed appraisal function weightVote(address nftAddress, uint tokenid, uint appraisal, uint seedNum) checkParticipation(nftAddress, tokenid) nonReentrant external { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; require(sessionCheck.sessionProgression < 2 && sessionCore.endTime < block.timestamp && sessionMap.voterCheck[msg.sender] == 1 && sessionMap.nftVotes[msg.sender].concealedAppraisal == keccak256(abi.encodePacked(appraisal, msg.sender, seedNum)) && sessionCore.maxAppraisal >= appraisal ); sessionMap.voterCheck[msg.sender] = 2; if(sessionCheck.sessionProgression == 0) { sessionCheck.sessionProgression = 1; } _weigh(nftAddress, tokenid, appraisal); emit voteWeighed(msg.sender, nonce, nftAddress, tokenid, appraisal); if(sessionCheck.calls == sessionCore.uniqueVoters || sessionCore.endTime + sessionCore.votingTime < block.timestamp) { sessionCheck.sessionProgression = 2; sessionCore.uniqueVoters = sessionCheck.calls; sessionCheck.calls = 0; } } /// @notice takes average of appraisals and outputs a final appraisal value. /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function setFinalAppraisal(address nftAddress, uint tokenid) public { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; require( (block.timestamp > sessionCore.endTime + sessionCore.votingTime || sessionCheck.sessionProgression == 2) && sessionCheck.sessionProgression <= 2 ); Treasury.updateNftPriced(); if(sessionCheck.calls != 0) { sessionCore.uniqueVoters = sessionCheck.calls; } sessionCore.totalProfit += sessionCore.bounty; sessionCore.totalSessionStake += sessionCore.bounty; sessionCheck.calls = 0; sessionCheck.timeFinalAppraisalSet = block.timestamp; finalAppraisalValue[nonce][nftAddress][tokenid] = (sessionCore.totalAppraisalValue)/(sessionCore.totalVotes); sessionCheck.sessionProgression = 3; emit finalAppraisalDetermined(nftNonce[nftAddress][tokenid], nftAddress, tokenid, finalAppraisalValue[nftNonce[nftAddress][tokenid]][nftAddress][tokenid], sessionCore.uniqueVoters, sessionCore.totalSessionStake); } /// @notice Calculates users base and harvests their loss before returning remaining stake /** @dev A couple notes: 1. Base is calculated based on margin of error. > +/- 5% = 1 > +/- 4% = 2 > +/- 3% = 3 > +/- 2% = 4 > +/- 1% = 5 > Exact = 6 2. winnerPoints are calculated based on --> base * stake 3. Losses are harvested based on --> (margin of error - 5%) * stake */ /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function harvest(address nftAddress, uint tokenid) checkParticipation(nftAddress, tokenid) nonReentrant external { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; require( sessionCheck.sessionProgression == 3 && sessionMap.voterCheck[msg.sender] == 2 ); sessionCheck.calls++; sessionMap.voterCheck[msg.sender] = 3; _harvest(nftAddress, tokenid); sessionMap.nftVotes[msg.sender].stake -= sessionMap.amountHarvested[msg.sender]; uint commission = PostSessionLibrary.setCommission(address(Treasury).balance).mul(sessionMap.amountHarvested[msg.sender]).div(10000); sessionCore.totalSessionStake -= commission; sessionMap.amountHarvested[msg.sender] -= commission; sessionCore.totalProfit += sessionMap.amountHarvested[msg.sender]; Treasury.updateProfitGenerated(sessionMap.amountHarvested[msg.sender]); (bool sent, ) = payable(Treasury).call{value: commission}(""); require(sent); emit userHarvested(msg.sender, nonce, nftAddress, tokenid, sessionMap.amountHarvested[msg.sender]); if(sessionCheck.calls == sessionCore.uniqueVoters) { sessionCheck.sessionProgression = 4; sessionCore.uniqueVoters = sessionCheck.calls; sessionCheck.calls = 0; } } /// @notice User claims principal stake along with any earned profits in ETH or ABC form /** @dev 1. Calculates user principal return value 2. Enacts sybil defense mechanism 3. Edits totalProfits and totalSessionStake to reflect claim 5. Pays out principal 6. Adds profit credit to profitStored */ /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function claim(address nftAddress, uint tokenid) checkParticipation(nftAddress, tokenid) nonReentrant external returns(uint) { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; if (sessionCheck.timeFinalAppraisalSet == 0) { require( sessionCheck.sessionProgression == 4 || block.timestamp > (sessionCore.endTime + sessionCore.votingTime * 2) ); } else{ require( (block.timestamp > sessionCheck.timeFinalAppraisalSet + sessionCore.votingTime || sessionCheck.sessionProgression == 4) && sessionCheck.sessionProgression <= 4 && sessionMap.voterCheck[msg.sender] == 3 ); } uint principalReturn; sessionMap.voterCheck[msg.sender] = 4; if(sessionCheck.sessionProgression == 3) { sessionCore.uniqueVoters = sessionCheck.calls; sessionCheck.calls = 0; sessionCheck.sessionProgression = 4; } if(sessionCheck.correct * 100 / (sessionCheck.correct + sessionCheck.incorrect) >= 90) { principalReturn += sessionMap.nftVotes[msg.sender].stake + sessionMap.amountHarvested[msg.sender]; } else { principalReturn += sessionMap.nftVotes[msg.sender].stake; } sessionCheck.calls++; uint payout; if(sessionMap.winnerPoints[msg.sender] == 0) { payout = 0; } else { payout = sessionCore.totalProfit * sessionMap.winnerPoints[msg.sender] / sessionCore.totalWinnerPoints; } profitStored[msg.sender] += payout; sessionCore.totalProfit -= payout; sessionCore.totalSessionStake -= payout + principalReturn; principalStored[msg.sender] += principalReturn; sessionCore.totalWinnerPoints -= sessionMap.winnerPoints[msg.sender]; sessionMap.winnerPoints[msg.sender] = 0; if(sessionCheck.calls == sessionCore.uniqueVoters || block.timestamp > sessionCheck.timeFinalAppraisalSet + sessionCore.votingTime*2) { sessionCheck.sessionProgression = 5; _executeEnd(nftAddress, tokenid); return 0; } return 1; } /// @notice Custodial function to clear funds and remove session as child /// @dev Caller receives 10% of the funds that are meant to be cleared /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function endSession(address nftAddress, uint tokenid) public { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; if (sessionCheck.timeFinalAppraisalSet == 0) { revert(); } else{ require( (block.timestamp > sessionCheck.timeFinalAppraisalSet + sessionCore.votingTime * 2 || sessionCheck.sessionProgression == 5) ); _executeEnd(nftAddress, tokenid); } } /* ======== INTERNAL FUNCTIONS ======== */ function _weigh(address nftAddress, uint tokenid, uint appraisal) internal { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; sessionMap.nftVotes[msg.sender].appraisal = appraisal; uint weight = sqrtLibrary.sqrt(sessionMap.nftVotes[msg.sender].stake/sessionCore.lowestStake); sessionCore.totalVotes += weight; sessionCheck.calls++; sessionCore.totalAppraisalValue = sessionCore.totalAppraisalValue.add((weight) * appraisal); } function _harvest(address nftAddress, uint tokenid) internal { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; VotingSessionMapping storage sessionMap = NftSessionMap[nonce][nftAddress][tokenid]; sessionMap.nftVotes[msg.sender].base = PostSessionLibrary.calculateBase( finalAppraisalValue[nftNonce[nftAddress][tokenid]][nftAddress][tokenid], sessionMap.nftVotes[msg.sender].appraisal ); uint weight = sqrtLibrary.sqrt(sessionMap.nftVotes[msg.sender].stake/sessionCore.lowestStake); if(sessionMap.nftVotes[msg.sender].base > 0) { sessionCore.totalWinnerPoints += sessionMap.nftVotes[msg.sender].base * weight; sessionMap.winnerPoints[msg.sender] = sessionMap.nftVotes[msg.sender].base * weight; sessionCheck.correct += weight; } else { sessionCheck.incorrect += weight; } sessionMap.amountHarvested[msg.sender] = PostSessionLibrary.harvest( sessionMap.nftVotes[msg.sender].stake, sessionMap.nftVotes[msg.sender].appraisal, finalAppraisalValue[nftNonce[nftAddress][tokenid]][nftAddress][tokenid] ); } /// @notice executes custodial actions to end a session /** @dev Clears session claims to funds, distributes 95% of residual funds to treasury and the other 5% to the caller. Then proceeds to set the total session stake to 0 and emit an end session event to signify session completion. */ /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function _executeEnd(address nftAddress, uint tokenid) internal { uint nonce = nftNonce[nftAddress][tokenid]; VotingSessionCore storage sessionCore = NftSessionCore[nonce][nftAddress][tokenid]; VotingSessionChecks storage sessionCheck = NftSessionCheck[nonce][nftAddress][tokenid]; sessionCheck.sessionProgression = 5; uint tPayout = 97*sessionCore.totalSessionStake/100; uint cPayout = sessionCore.totalSessionStake - tPayout; (bool sent, ) = payable(Treasury).call{value: tPayout}(""); require(sent); (bool sent1, ) = msg.sender.call{value: cPayout}(""); require(sent1); sessionCore.totalSessionStake = 0; emit sessionEnded(nftAddress, tokenid, nftNonce[nftAddress][tokenid]); } /* ======== FUND INCREASE ======== */ /// @notice allow any user to add additional bounty on session of their choice /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function addToBounty(address nftAddress, uint tokenid) payable external { VotingSessionCore storage sessionCore = NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid]; require(sessionCore.endTime > block.timestamp); sessionCore.bounty += msg.value; sessionCore.totalSessionStake += msg.value; emit bountyIncreased(msg.sender, nftNonce[nftAddress][tokenid], nftAddress, tokenid, msg.value); } /* ======== VIEW FUNCTIONS ======== */ /// @notice returns the status of the session in question /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function getStatus(address nftAddress, uint tokenid) view public returns(uint) { return NftSessionCheck[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].sessionProgression; } /// @notice returns the current spot exchange rate of ETH to ABC function ethToAbc() view public returns(uint) { return 1e18 / (0.00005 ether + 0.000015 ether * Treasury.tokensClaimed() / (1000000*1e18)); } /// @notice returns the payout earned from the current session /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised function getEthPayout(address nftAddress, uint tokenid) view external returns(uint) { VotingSessionCore storage sessionCore = NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid]; if(sessionCore.totalWinnerPoints == 0) { return 0; } return sessionCore.totalSessionStake * NftSessionMap[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].winnerPoints[msg.sender] / sessionCore.totalWinnerPoints; } /// @notice check the users status in terms of session interaction /// @param nftAddress NFT contract address of NFT being appraised /// @param tokenid NFT tokenid of NFT being appraised /// @param _user appraisooooor who's session progress is of interest function getVoterCheck(address nftAddress, uint tokenid, address _user) view external returns(uint) { return NftSessionMap[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].voterCheck[_user]; } /* ======== FALLBACK FUNCTIONS ======== */ receive() external payable {} fallback() external payable {} /* ======== MODIFIERS ======== */ /// @notice stop users from being able to create multiple sessions for the same NFT at the same time modifier stopOverwrite( address nftAddress, uint tokenid ) { require( nftNonce[nftAddress][tokenid] == 0 || getStatus(nftAddress, tokenid) == 5 || block.timestamp > NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].endTime + NftSessionCore[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].votingTime * 3 ); _; } /// @notice makes sure that a user that submits a vote satisfies the proper voting parameters modifier properVote( address nftAddress, uint tokenid, uint stake ) { require( NftSessionMap[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].voterCheck[msg.sender] == 0 && stake >= 0.005 ether ); _; } /// @notice checks the participation of the msg.sender modifier checkParticipation( address nftAddress, uint tokenid ) { require(NftSessionMap[nftNonce[nftAddress][tokenid]][nftAddress][tokenid].voterCheck[msg.sender] > 0); _; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "./interfaces/IERC20.sol"; /// @author Medici /// @title Treasury contract for Abacus contract ABCTreasury { /* ======== UINT ======== */ uint public nftsPriced; uint public profitGenerated; uint public tokensClaimed; /* ======== ADDRESS ======== */ address public auction; address public pricingSession; address public admin; address public ABCToken; address public multisig; /* ======== CONSTRUCTOR ======== */ constructor() { admin = msg.sender; } /* ======== ADMIN FUNCTIONS ======== */ /// @notice set ABC token contract address /// @param _ABCToken desired ABC token to be stored and referenced in contract function setABCTokenAddress(address _ABCToken) onlyAdmin external { require(ABCToken == address(0)); ABCToken = _ABCToken; } function setMultisig(address _multisig) onlyAdmin external { multisig = _multisig; } /// @notice allow admin to withdraw funds to multisig in the case of emergency (ONLY USED IN THE CASE OF EMERGENCY) /// @param _amountAbc value of ABC to be withdrawn from the treasury to multisig (ONLY USED IN THE CASE OF EMERGENCY) /// @param _amountEth value of ETH to be withdrawn from the treasury to multisig (ONLY USED IN THE CASE OF EMERGENCY) function withdraw(uint _amountAbc, uint _amountEth) onlyAdmin external { IERC20(ABCToken).transfer(multisig, _amountAbc); (bool sent, ) = payable(multisig).call{value: _amountEth}(""); require(sent, "Failed to send Ether"); } /// @notice set newAdmin (or burn admin when the time comes) /// @param _newAdmin desired admin address to be stored and referenced in contract function setAdmin(address _newAdmin) onlyAdmin external { admin = _newAdmin; } /// @notice set pricing factory address to allow for updates /// @param _pricingFactory desired pricing session principle address to be stored and referenced in contract function setPricingSession(address _pricingFactory) onlyAdmin external { pricingSession = _pricingFactory; } /// @notice set auction contract for bounty auction period /// @param _auction desired auction address to be stored and referenced in contract function setAuction(address _auction) onlyAdmin external { auction = _auction; } /* ======== CHILD FUNCTIONS ======== */ /// @notice send ABC to users that earn /// @param recipient the user that will be receiving ABC /// @param _amount the amount of ABC to be transferred to the recipient function sendABCToken(address recipient, uint _amount) external { require(msg.sender == pricingSession || msg.sender == admin); IERC20(ABCToken).transfer(recipient, _amount); tokensClaimed += _amount; } /// @notice Allows Factory contract to update the profit generated value /// @param _amount the amount of profit to update profitGenerated count function updateProfitGenerated(uint _amount) isFactory external { profitGenerated += _amount; } /// @notice Allows Factory contract to update the amount of NFTs that have been priced function updateNftPriced() isFactory external { nftsPriced++; } /* ======== FALLBACKS ======== */ receive() external payable {} fallback() external payable {} /* ======== MODIFIERS ======== */ ///@notice check that msg.sender is admin modifier onlyAdmin() { require(admin == msg.sender, "not admin"); _; } ///@notice check that msg.sender is factory modifier isFactory() { require(msg.sender == pricingSession, "not session contract"); _; } }
pragma solidity ^0.8.0; /** * @title Helps contracts guard against reentrancy attacks. * @author Remco Bloemen <[email protected]π.com>, Eenae <[email protected]> * @dev If you mark a function `nonReentrant`, you should also * mark it `external`. */ contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter = 1; /** * @dev Prevents a contract from calling itself, directly or indirectly. * If you mark a function `nonReentrant`, you should also * mark it `external`. Calling one `nonReentrant` function from * another is not supported. Instead, you can implement a * `private` function doing the actual work, and an `external` * wrapper marked as `nonReentrant`. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter); } }
pragma solidity ^0.8.0; interface IABCTreasury { function sendABCToken(address recipient, uint _amount) external; function getTokensClaimed() external view returns(uint); function updateNftPriced() external; function updateProfitGenerated(uint _amount) external; }
pragma solidity ^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, 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) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * 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); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; library sqrtLibrary { function sqrt(uint x) pure internal returns (uint y) { uint z = (x + 1) / 2; y = x; while (z < y) { y = z; z = (x / z + z) / 2; } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "./sqrtLibrary.sol"; library PostSessionLibrary { using sqrtLibrary for *; ///////////////////// /// Base /// ///////////////////// function calculateBase(uint finalAppraisalValue, uint userAppraisalValue) pure internal returns(uint){ uint base = 1; uint userVal = 100 * userAppraisalValue; for(uint i=5; i >= 1; i--) { uint lowerOver = (100 + (i - 1)) * finalAppraisalValue; uint upperOver = (100 + i) * finalAppraisalValue; uint lowerUnder = (100 - i) * finalAppraisalValue; uint upperUnder = (100 - i + 1) * finalAppraisalValue; if (lowerOver < userVal && userVal <= upperOver) { return base; } if (lowerUnder < userVal && userVal <= upperUnder) { return base; } base += 1; } if(userVal == 100*finalAppraisalValue) { return 6; } return 0; } ///////////////////// /// Harvest /// ///////////////////// // function harvestUserOver(uint _stake, uint _userAppraisal, uint _finalAppraisal) pure internal returns(uint) { // return _stake * (_userAppraisal*100 - 105*_finalAppraisal)/(_finalAppraisal*100); // } // function harvestUserUnder(uint _stake, uint _userAppraisal, uint _finalAppraisal) pure internal returns(uint) { // return _stake * (95*_finalAppraisal - 100*_userAppraisal)/(_finalAppraisal*100); // } function harvest(uint _stake, uint _userAppraisal, uint _finalAppraisal) pure internal returns(uint) { if(_userAppraisal*100 > 105*_finalAppraisal) { return _stake * (_userAppraisal*100 - 105*_finalAppraisal)/(_finalAppraisal*100); } else if(_userAppraisal*100 < 95*_finalAppraisal) { return _stake * (95*_finalAppraisal - 100*_userAppraisal)/(_finalAppraisal*100); } else { return 0; } } ///////////////////// /// Commission /// ///////////////////// function setCommission(uint _treasurySize) pure internal returns(uint) { if (_treasurySize < 25000 ether) { return 500; } else if(_treasurySize >= 25000 ether && _treasurySize < 50000 ether) { return 400; } else if(_treasurySize >= 50000 ether && _treasurySize < 100000 ether) { return 300; } else if(_treasurySize >= 100000 ether && _treasurySize < 2000000 ether) { return 200; } else if(_treasurySize >= 200000 ether && _treasurySize < 400000 ether) { return 100; } else if(_treasurySize >= 400000 ether && _treasurySize < 700000 ether) { return 50; } else { return 25; } } }
// SPDX-License-Identifier: MIT pragma solidity ^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); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_highestBidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"_highestBid","type":"uint256"},{"indexed":false,"internalType":"address","name":"_nftAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_initialAppraisal","type":"uint256"}],"name":"auctionEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"_bidAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_nftAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_initialAppraisal","type":"uint256"}],"name":"newBidSubmitted","type":"event"},{"inputs":[],"name":"ABCToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"uint256","name":"_tokenid","type":"uint256"}],"name":"addToBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"uint256","name":"_tokenid","type":"uint256"},{"internalType":"uint256","name":"_initialAppraisal","type":"uint256"}],"name":"changeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"firstSession","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"highestBid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"highestBidder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"uint256","name":"_tokenid","type":"uint256"},{"internalType":"uint256","name":"_initialAppraisal","type":"uint256"}],"name":"newBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"session","outputs":[{"internalType":"contract PricingSession","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setFirst","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_session","type":"address"}],"name":"setSessionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract ABCTreasury","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userVote","outputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenid","type":"uint256"},{"internalType":"uint256","name":"intitialAppraisal","type":"uint256"},{"internalType":"uint256","name":"bid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052600160005534801561001557600080fd5b5033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460146101000a81548160ff021916908315150217905550612614806100816000396000f3fe6080604052600436106101355760003560e01c80639d6a0f28116100ab578063d8ac34ee1161006f578063d8ac34ee146103e6578063dc37596d1461040f578063f0f442601461044f578063f851a44014610478578063faf206c2146104a3578063fe67a54b146104ce57610135565b80639d6a0f28146102ed578063a2fb117514610318578063a6fe2c5514610355578063affed0e01461037e578063b14c63c5146103a957610135565b8063451df52e116100fd578063451df52e146102105780634e71d92d1461024d5780635711b8f9146102645780635e3568b81461027b57806361d027b3146102a657806375b37d92146102d157610135565b8063144fa6d71461013a5780632d16502f146101635780633b22e0481461018c5780634223ac0f146101a857806344c816fa146101d3575b600080fd5b34801561014657600080fd5b50610161600480360381019061015c9190612069565b6104e5565b005b34801561016f57600080fd5b5061018a600480360381019061018591906120ce565b610583565b005b6101a660048036038101906101a19190612092565b610797565b005b3480156101b457600080fd5b506101bd610b56565b6040516101ca919061225d565b60405180910390f35b3480156101df57600080fd5b506101fa60048036038101906101f59190612146565b610b7c565b60405161020791906123cf565b60405180910390f35b34801561021c57600080fd5b5061023760048036038101906102329190612146565b610b94565b604051610244919061225d565b60405180910390f35b34801561025957600080fd5b50610262610bc7565b005b34801561027057600080fd5b50610279610e74565b005b34801561028757600080fd5b50610290610f12565b60405161029d91906123b4565b60405180910390f35b3480156102b257600080fd5b506102bb610f38565b6040516102c89190612399565b60405180910390f35b6102eb60048036038101906102e691906120ce565b610f5e565b005b3480156102f957600080fd5b50610302611599565b60405161030f919061237e565b60405180910390f35b34801561032457600080fd5b5061033f600480360381019061033a9190612146565b6115ac565b60405161034c919061225d565b60405180910390f35b34801561036157600080fd5b5061037c6004803603810190610377919061211d565b6115df565b005b34801561038a57600080fd5b50610393611656565b6040516103a091906123cf565b60405180910390f35b3480156103b557600080fd5b506103d060048036038101906103cb9190612146565b61165c565b6040516103dd91906123cf565b60405180910390f35b3480156103f257600080fd5b5061040d60048036038101906104089190612069565b611674565b005b34801561041b57600080fd5b5061043660048036038101906104319190612198565b611712565b6040516104469493929190612339565b60405180910390f35b34801561045b57600080fd5b5061047660048036038101906104719190612069565b61176f565b005b34801561048457600080fd5b5061048d61180d565b60405161049a919061225d565b60405180910390f35b3480156104af57600080fd5b506104b8611833565b6040516104c5919061237e565b60405180910390f35b3480156104da57600080fd5b506104e3611846565b005b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461053f57600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff16600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141580156106415750600460149054906101000a900460ff165b61064a57600080fd5b82600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555080600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020181905550505050565b60016000808282546107a991906123f5565b925050819055506000805490506006600060055481526020019081526020016000205434600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015461082d91906123f5565b1180156108465750600460149054906101000a900460ff165b80156109b557506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632171d26e85856040518363ffffffff1660e01b81526004016108ac929190612278565b60206040518083038186803b1580156108c457600080fd5b505afa1580156108d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fc919061216f565b14806109b457506005600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ce0ef9585856040518363ffffffff1660e01b8152600401610962929190612278565b60206040518083038186803b15801561097a57600080fd5b505afa15801561098e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b2919061216f565b145b5b6109be57600080fd5b34600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003016000828254610a2391906123f5565b925050819055503360076000600554815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301546006600060055481526020019081526020016000208190555034600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b3c91906123f5565b925050819055506000548114610b5157600080fd5b505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60086020528060005260406000206000915090505481565b60076020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001600080828254610bd991906123f5565b9250508190555060008054905060003373ffffffffffffffffffffffffffffffffffffffff1660076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cf257600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550610d95565b600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610d92919061244b565b90505b80600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610de4919061244b565b9250508190555060003373ffffffffffffffffffffffffffffffffffffffff1682604051610e1190612248565b60006040518083038185875af1925050503d8060008114610e4e576040519150601f19603f3d011682016040523d82523d6000602084013e610e53565b606091505b5050905080610e6157600080fd5b50506000548114610e7157600080fd5b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ece57600080fd5b600460149054906101000a900460ff1615600460146101000a81548160ff02191690831515021790555060056000815480929190610f0b90612521565b9190505550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001600080828254610f7091906123f5565b925050819055506000805490506006600060055481526020019081526020016000205434118015610fad5750600460149054906101000a900460ff165b801561111c57506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632171d26e86866040518363ffffffff1660e01b8152600401611013929190612278565b60206040518083038186803b15801561102b57600080fd5b505afa15801561103f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611063919061216f565b148061111b57506005600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634ce0ef9586866040518363ffffffff1660e01b81526004016110c9929190612278565b60206040518083038186803b1580156110e157600080fd5b505afa1580156110f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611119919061216f565b145b5b61112557600080fd5b42600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503360076000600554815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503460066000600554815260200190815260200160002081905550600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461127b919061244b565b9250508190555060003373ffffffffffffffffffffffffffffffffffffffff16600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301546040516112fd90612248565b60006040518083038185875af1925050503d806000811461133a576040519150601f19603f3d011682016040523d82523d6000602084013e61133f565b606091505b505090508061134d57600080fd5b84600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555082600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002018190555034600a6000600554815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003018190555034600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461153e91906123f5565b925050819055507f0e756fa4a9fc804a0b7895c41d5d9aec59ef49bd0e10fca02f7c0fcdb354d49a333487878760405161157c9594939291906122a1565b60405180910390a150600054811461159357600080fd5b50505050565b600460149054906101000a900460ff1681565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461163957600080fd5b80600460156101000a81548160ff02191690831515021790555050565b60055481565b60066020528060005260406000206000915090505481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146116ce57600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a602052816000526040600020602052806000526040600020600091509150508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154905084565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117c957600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460159054906101000a900460ff1681565b600160008082825461185891906123f5565b92505081905550600080549050600460159054906101000a900460ff16156118d557600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146118d457600080fd5b5b42600860006005548152602001908152602001600020541080156119055750600460149054906101000a900460ff165b61190e57600080fd5b6000600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905080600c600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611a21919061244b565b92505081905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166335d5593082600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154620151806040518663ffffffff1660e01b8152600401611c4b94939291906122f4565b6000604051808303818588803b158015611c6457600080fd5b505af1158015611c78573d6000803e3d6000fd5b50505050506000600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506201518042611d1c91906123f5565b60086000600560008154611d2f90612521565b9190508190558152602001908152602001600020819055507fd1ba2b9a4165eb401ff2d35ac2d070d2f0c4377230fdde5a3d0193cbb2340fc860076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154600a60006005548152602001908152602001600020600060076000600554815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154604051611ffb9594939291906122a1565b60405180910390a150600054811461201257600080fd5b50565b60008135905061202481612599565b92915050565b600081359050612039816125b0565b92915050565b60008135905061204e816125c7565b92915050565b600081519050612063816125c7565b92915050565b60006020828403121561207b57600080fd5b600061208984828501612015565b91505092915050565b600080604083850312156120a557600080fd5b60006120b385828601612015565b92505060206120c48582860161203f565b9150509250929050565b6000806000606084860312156120e357600080fd5b60006120f186828701612015565b93505060206121028682870161203f565b92505060406121138682870161203f565b9150509250925092565b60006020828403121561212f57600080fd5b600061213d8482850161202a565b91505092915050565b60006020828403121561215857600080fd5b60006121668482850161203f565b91505092915050565b60006020828403121561218157600080fd5b600061218f84828501612054565b91505092915050565b600080604083850312156121ab57600080fd5b60006121b98582860161203f565b92505060206121ca85828601612015565b9150509250929050565b6121dd8161247f565b82525050565b6121ec81612491565b82525050565b6121fb816124c7565b82525050565b61220a816124eb565b82525050565b6122198161250f565b82525050565b600061222c6000836123ea565b9150600082019050919050565b612242816124bd565b82525050565b60006122538261221f565b9150819050919050565b600060208201905061227260008301846121d4565b92915050565b600060408201905061228d60008301856121d4565b61229a6020830184612239565b9392505050565b600060a0820190506122b660008301886121d4565b6122c36020830187612239565b6122d060408301866121d4565b6122dd6060830185612239565b6122ea6080830184612239565b9695505050505050565b600060808201905061230960008301876121d4565b6123166020830186612239565b6123236040830185612239565b6123306060830184612210565b95945050505050565b600060808201905061234e60008301876121d4565b61235b6020830186612239565b6123686040830185612239565b6123756060830184612239565b95945050505050565b600060208201905061239360008301846121e3565b92915050565b60006020820190506123ae60008301846121f2565b92915050565b60006020820190506123c96000830184612201565b92915050565b60006020820190506123e46000830184612239565b92915050565b600081905092915050565b6000612400826124bd565b915061240b836124bd565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156124405761243f61256a565b5b828201905092915050565b6000612456826124bd565b9150612461836124bd565b9250828210156124745761247361256a565b5b828203905092915050565b600061248a8261249d565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006124d2826124d9565b9050919050565b60006124e48261249d565b9050919050565b60006124f6826124fd565b9050919050565b60006125088261249d565b9050919050565b600061251a826124bd565b9050919050565b600061252c826124bd565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561255f5761255e61256a565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6125a28161247f565b81146125ad57600080fd5b50565b6125b981612491565b81146125c457600080fd5b50565b6125d0816124bd565b81146125db57600080fd5b5056fea26469706673582212200af47740d8f46fe421630141fe84b91479f44423f3a5012178961363375eb0a564736f6c63430008000033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.