Function purchase( address recipient_, address referrer_, uint256 id_, uint256 amount_, uint256 minAmountOut_ ) external nonReentrant
Intended behavior.
allows users to exchange the
amountofquoteTokentopayoutToken.calculates the fee values for
referrer_if it exists and forProtocolif protocolFee was set.calculate the
payoutvalue forauctioneerwith passedid_foramountLessFeevalue.saves fee values for later withdrawal
transfer from the
msg.sendertheamountof thequoteTokentoken to contract address.over
callbackAddraddress or directly transfer thepayoutvalue of thepayoutTokenfrom marketownerto contract address.to
callbackAddraddress or directly transfer theamountLessFeevalue of thequoteTokenfrom contract address toownerof market.transferring tokens directly to the
recipient_address if it isInstantSwapor mint for therecipient_thepayoutamount of Bonds tokens which will be blocked for exchange to thepayoutTokenbefore theexpirytime.
Negative behavior.
msg.sendersent an insufficient number of thequoteTokentokenspayoutless thenminAmountOut_the market for the
id_doesn't exist; assure that ingetMarketInfoForPurchasefromBondBaseSDAthe market owner doesn’t have enough
payoutTokentokensif it isn’t
InstantSwapthenrecipient_shouldn't receivepayoutToken, but only Bonds tokensif it is
InstantSwapthenrecipient_shouldn’t receive the Bonds tokens, but onlypayoutToken.Shouldn’t allow transferring on behalf of other users.
Preconditions.
The market for the corresponding
id_should be registered inside the_aggregatorcontract, to do this, the address of theAuctioneerwhich store the markets must be whitelisted inside_aggregatorcontract.msg.sendershould have enoughquoteTokentokens ≥amountmarket owner should have enough
payoutToken≥payout
Postconditions.
if
callbackAddr != address(0), thenamountLessFeevalue ofquoteTokentokens should be successfully sent tocallbackAddrmsg.senderbalance ofquoteTokendecreased byamountquantity of tokensownerbalance ofpayoutTokendecreased bypayoutquantity of tokensif
InstantSwapthenrecipient_should successfully receive thepayoutvalue ofpayoutTokenif it isn’t
InstantSwapthenrecipient_received thepayoutvalue of Bond tokens with the corresponding non-zero expiry timerewardsincreased for non-zeroreferrer_bytoReferreramount ofquoteTokentokensrewardsincreased for_protocolby non-zerotoProtocolamount ofquoteTokentokens
Inputs.
address recipient_ - controlled. can be any address
address referrer_ - controlled. can be any address
uint256 id_ - controlled. used to select market
uint256 amount_ - controlled, amount of
quoteTokenwhichmsg.sendershould transfer to contract, there is a check inside the_handleTransfersfunctionuint256 minAmountOut* - controlled, min amount of
payouttokens, whichrecipient*will receive, there is a check inside theauctioneer.purchaseBondfunction
Examine all function calls the function makes.
a. Call to
IBondAuctioneer auctioneer = aggregator.getAuctioneer(id_)What is controllable? (callee, params, return value):
id_- controlled,msg.sendercan choose any createdauctioneerby theirid_value. only a whitelisted contract can become anauctioneer.If return value controllable, how is it used and how can it go wrong? if
auctioneerfor currentid_doesn’t exist, thengetAuctioneerfunction will returnaddress(0)otherwise will returnauctioneeraddress which has created the market.What happens if it reverts or tries to reenter?
aggregator- is a trusted contract address, no problems here
b. Call to
auctioneer.getMarketInfoForPurchase(id_)What is controllable? (callee, params, return value):
id_- controlled. it is unique market identificationIf return value controllable, how is it used and how can it go wrong? address owner - market owner address can be any user. should transfer the necessary amount of
payoutToken; address payoutToken - controlled, any user can create a market with any token address; address quoteToken - controlled, any user can create a market with any token address; uint48 vesting - controlled, any user can create a market with any vesting time. However, the values are controlled, the user must transfer the appropriate number of tokens for exchange. if these are dummy tokens, users will not exchange them.What happens if it reverts or tries to reenter? No problem
c. Call to
auctioneer.purchaseBond(id_, amountLessFee, minAmountOut_)What is controllable? (callee, params, return value):
id_- controlled;amountLessFee- partially controlled because it's an amount value minus the fee values;minAmountOut_- controlled, ifpayoutless thanminAmountOut_, transaction should be rejected.If return value controllable, how is it used and how can it go wrong? as a result of calculation errors, the user may receive more
payouttokens than he should; ifpayoutvalue is less thanminAmountOut_, the transaction should be canceled.What happens if it reverts or tries to reenter? Can revert in case if
payoutvalue is less thanminAmountOut_, expected behavior.
d. Call to
handleTransfers(id, amount_, payout, toReferrer + toProtocol)What is controllable? (callee, params, return value):
id_- controlled;amount_- controlled, there is a check thatmsg.sendertransfer no less thanamount_to contract address;payout- uncontrolled, there is a check that owner transfer no less thanpayoutto contract address;toReferrer + toProtocol- uncontrolledIf return value controllable, how is it used and how can it go wrong?
What happens if it reverts or tries to reenter?
f. Call to
handlePayout(recipient, payout, payoutToken, vesting): full review in the description ofBondFixedTermTeller.sol