code-423n4 / 2024-02-tapioca-findings

1 stars 1 forks source link

AirdropBroker / TapiocaOptionBroker cannot ensure that paymentTokenValuation's decimals in _getDiscountedPaymentAmount is 18 #166

Closed c4-bot-6 closed 3 months ago

c4-bot-6 commented 4 months ago

Lines of code

https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/options/TapiocaOptionBroker.sol#L579 https://github.com/Tapioca-DAO/tap-token/blob/20a83b1d2d5577653610a6c3879dff9df4968345/contracts/option-airdrop/AirdropBroker.sol#L525

Vulnerability details

Despite the developer comments indicating that the decimals should be all 18, but we can find some real ITapiocaOracle implementations in the https://github.com/Tapioca-DAO/tapioca-periph/blob/032396f701be935b04a7e5cf3cb40a0136259dbc/contracts/oracle/implementation/ . Them shows that the decimals of oracle USD prices returned from ITapiocaOracle implementations can be 30 https://github.com/Tapioca-DAO/tapioca-periph/blob/032396f701be935b04a7e5cf3cb40a0136259dbc/contracts/oracle/implementation/Arbitrum/GLPOracle.sol#L26,

    function decimals() external pure returns (uint8) {
        return 30;
    }

or dynamic setting https://github.com/Tapioca-DAO/tapioca-periph/blob/032396f701be935b04a7e5cf3cb40a0136259dbc/contracts/oracle/SeerUniSolo.sol#L21 :

    constructor(
        ...
        uint8 _decimals,
        OracleUniSoloConstructorData memory _oracleUniSoloConstructorData
    ) OracleUniSolo(_oracleUniSoloConstructorData) {
        ...
        decimals = _decimals;

Impact

We can find the logic for calculating the payment token amount based on the oracle USD value in the _getDiscountedPaymentAmount method:

uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

So if the USD values from different oracles have different decimals like they are in the above implementations, the rawPaymentAmount will be scaled by 10 ** the difference in their decimals.

Recommendation

Read the actual decimals() from the oracle and scale both _otcAmountInUSD and _paymentTokenValuation to 1e18 as USD values.

Assessed type

Decimal

tapiocadao commented 4 months ago

As the report states, the payment token is explicitly stated in documentation to only ever be Native USDC or USDO.

Secondly, the GLP oracle in question is for a Singularity market and would never be used for exercising options, therefore this is invalid.

c4-sponsor commented 4 months ago

tapiocadao (sponsor) disputed

c4-judge commented 3 months ago

dmvt marked the issue as primary issue

c4-judge commented 3 months ago

dmvt marked the issue as unsatisfactory: Invalid