DEV Community

THE CODE DOCTOR
THE CODE DOCTOR

Posted on

1

03.DEFI ATTACKS - Falsche Slippagekalkulation

Die Slippage-Parameter sollten in etwa als "minTokensOut" definiert sein – also die minimale Anzahl an Token, die der Nutzer bei einem Swap akzeptieren würde. Alles, was davon abweicht, sollte als Warnsignal betrachtet werden, da dies höchstwahrscheinlich einen fehlerhaften Slippage-Parameter darstellt.

Zur Veranschaulichung könnte man sich diesen vereinfachten Code aus OpenZeppelins Audit von Origin Dollar ansehen. Hierbei wird gezeigt, dass falsche oder ungenaue Slippage-Parameter potenziell zu einem ungewollten Verlust von Vermögenswerten führen können, wenn der minimale Token-Ausgang nicht korrekt festgelegt ist.

function withdraw(address _recipient, address _asset, uint256 _amount
) external onlyVault nonReentrant {
    // ...

    // Calculate how much of the pool token we need to withdraw
    (uint256 contractPTokens, , uint256 totalPTokens) = _getTotalPTokens();

    uint256 poolCoinIndex = _getPoolCoinIndex(_asset);
    // Calculate the max amount of the asset we'd get if we withdrew all the
    // platform tokens
    ICurvePool curvePool = ICurvePool(platformAddress);
    uint256 maxAmount = curvePool.calc_withdraw_one_coin(
        totalPTokens,
        int128(poolCoinIndex)
    );

    // Calculate how many platform tokens we need to withdraw the asset amount
    uint256 withdrawPTokens = totalPTokens.mul(_amount).div(maxAmount);

    // Calculate a minimum withdrawal amount
    uint256 assetDecimals = Helpers.getDecimals(_asset);
    // 3crv is 1e18, subtract slippage percentage and scale to asset
    // decimals
    // @audit not using user-provided _amount, but calculating a non-sensical
    // value based on the LP tokens
    uint256 minWithdrawAmount = withdrawPTokens
        .mulTruncate(uint256(1e18).sub(maxSlippage))
        .scaleBy(int8(assetDecimals - 18));

    curvePool.remove_liquidity_one_coin(
        withdrawPTokens,
        int128(poolCoinIndex),
        minWithdrawAmount
    );

    // ...
}
Enter fullscreen mode Exit fullscreen mode

Und die korrigierte Version nach dem Audit:

curvePool.remove_liquidity_one_coin(
    withdrawPTokens,
    int128(poolCoinIndex),
    _amount
);
Enter fullscreen mode Exit fullscreen mode

Auditoren sollten sicherstellen, dass die Slippage-Parameter klar definiert sind und keine versteckten Risiken für den Benutzer darstellen.

Weitere Beispiele findest du in den folgenden Verweisen:
1 - [H-15] Wrong slippage protection on Token -> Token trades,
2 - Ineffective slippage mechanism when redeeming proportionally,
3 - Slippage/Minimum amount does not work during single-side redemption,
4 - Illuminate's PT doesn't respect users' slippage specifications for underlying,
5 - Oracle slippage rate is used for checking primary and secondary ratio,
6 - WithdrawPeriphery uses incorrect value for MAX_BPS which will allow much higher slippage than intended,
7 - ,
8 - [M-05] Wrong slippage check,
9 - IchiSpell applies slippage to sqrtPrice which is wrong and leads to unpredictable slippage.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more