payParams function prevents users from specifying minReturnedTokens, when using the swap pathway #47
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-232
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2023-05-juicebox/blob/9d0458282511ff269b3b35b5b082b56d5cc08663/juice-buyback/contracts/JBXBuybackDelegate.sol#L166
Vulnerability details
Impact
The
payParams
function will cause thepay()
function in the terminal (used to call in theJBXBuybackDelegate
contract) to revert, if the user specify a minimum amount of token to mint (other than 0), while the swap pathway is selected. Preventing the user from being able to specify the minimum amount of tokens to receive.(They can still specify the splippage in the swap, but
didPay()
, will mint the tokens instead if such criteria is not met https://github.com/code-423n4/2023-05-juicebox/blob/9d0458282511ff269b3b35b5b082b56d5cc08663/juice-buyback/contracts/JBXBuybackDelegate.sol#L205).Proof of Concept
One of the values returned by
payParams
will be set to 0 each time the swap pathway is taken.This value will later cause the following statement to revert:
if (beneficiaryTokenCount < _minReturnedTokens) revert INADEQUATE_TOKEN_COUNT();
(in thepay()
function, from the terminal contract) for any value of_minReturnedTokens !=0
. More in detail:"If the amount swapped is bigger than the lowest received when minting" , the
payParams
function will returun the following values:(As can be seen here: https://github.com/code-423n4/2023-05-juicebox/blob/9d0458282511ff269b3b35b5b082b56d5cc08663/juice-buyback/contracts/JBXBuybackDelegate.sol#L156 ,
https://github.com/code-423n4/2023-05-juicebox/blob/9d0458282511ff269b3b35b5b082b56d5cc08663/juice-buyback/contracts/JBXBuybackDelegate.sol#L166 ).
Those values (the
0
in particular) are used by therecordPaymentFrom()
in theJBSingleTokenPaymentTerminalStore3_1.sol
contract. Which callspayParams
to set_weight
:(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/JBSingleTokenPaymentTerminalStore3_1.sol#L370)
and than uses the result to decide what to return:
(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/JBSingleTokenPaymentTerminalStore3_1.sol#L415).
This operations are invoked by the
pay()
function of theJBPayoutRedemptionPaymentTerminal3_1
contract, to set the following parameters:(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_1.sol#L1470).
As you might see from the calls above, when the swap pathway is taken
_tokenCount
in the previous call will be set to0
.In the instructions right below this, the pay function will check if
_tokenCount
is greater than 0, to decide weather or not it should mint some tokens to the beneficiary:(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_1.sol#L1481)
Since
_tokenCount == 0
,beneficiaryTokenCount
will keep it's uninitialized vale of0
and the check right bellow will fail for any value of_minReturnedTokens
diffrent from 0:(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_1.sol#L1493)
_minReturnedTokens
being the value passed to thepay()
function to specify the minimum amount of tokens to mint.(https://github.com/jbx-protocol/juice-contracts-v3/blob/12d852f28d372dd44987586f8009c56b0fe247a9/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_1.sol#L1437)
Here is a Forgery test that you can run. It checks for a revert with error:
INADEQUATE_TOKEN_COUNT
(on line171
):The test will fail when
_minReturnedTokens
is set to 0, and pass for the other values.Recommended Mitigation Steps
The
if (beneficiaryTokenCount < _minReturnedTokens) revert INADEQUATE_TOKEN_COUNT();
check should only be performed when_tokenCount > 0
.Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: