code-423n4 / 2024-01-renft-findings

2 stars 0 forks source link

Token Balance Skimming issue #540

Closed c4-bot-6 closed 10 months ago

c4-bot-6 commented 10 months ago

Lines of code

https://github.com/re-nft/smart-contracts/blob/3ddd32455a849c3c6dc3c3aad7a33a6c9b44c291/src/modules/PaymentEscrow.sol#L397-L412

Vulnerability details

vulnerability details

the skim function is for calculate and extract the skimmedBalance based on the difference between the actual token balance (trueBalance) of the contract and the recorded balance (syncedBalance), the vulnerability arises when tokens are directly transferred to the contract's address, bypassing the designed deposit mechanisms. This inflates trueBalance without a corresponding update to syncedBalance, leading to incorrect skimmedBalance calculation.

Impact

the vulnerability is Allows unauthorized extraction of tokens, potentially leading to financial losses.

Proof of Concept

as scenario let's say: The contract has a recorded balance (syncedBalance) of 1000 tokens, An external interaction (not a direct transfer, but perhaps through a complex contract interaction) reduces the actual balance (trueBalance) of the contract to 500 tokens without updating syncedBalance here is a foundry test :

contract PaymentEscrowTest is Test {
    Kernel kernel;
    PaymentEscrow paymentEscrow;
    MockERC20 mockERC20;
    address proxyAddress = address(1); // Example proxy address

    function setUp() public {
        kernel = new Kernel();
        paymentEscrow = new PaymentEscrow(kernel);
        mockERC20 = new MockERC20("MockToken", "MTK", 18);

        // Initialize the contract via proxy
        vm.prank(proxyAddress);
        paymentEscrow.MODULE_PROXY_INSTANTIATION(kernel);

        // Set permissions for skim function
        // Note: This requires specific implementation details of the contract's permission system
        // ...

        // Legitimate token deposit
        uint256 depositAmount = 1000 ether;
        mockERC20.transfer(address(paymentEscrow), depositAmount);
        vm.prank(proxyAddress);
        paymentEscrow.increaseDeposit(address(mockERC20), depositAmount);
    }

    function testSkimFunctionWithDirectTransfer() public {
        // Direct transfer to inflate trueBalance
        uint256 directTransferAmount = 500 ether;
        mockERC20.transfer(address(paymentEscrow), directTransferAmount);

        // Execute skim function
        vm.prank(proxyAddress);
        paymentEscrow.skim(address(mockERC20), address(this));

        // Verify the outcome
        uint256 contractBalanceAfterSkim = mockERC20.balanceOf(address(paymentEscrow));
        uint256 expectedBalance = depositAmount - directTransferAmount;
        assertEq(contractBalanceAfterSkim, expectedBalance, "Skim function did not behave as expected");
    }
}

Tools Used

Assessed type

Other

c4-pre-sort commented 10 months ago

141345 marked the issue as insufficient quality report

c4-judge commented 10 months ago

0xean marked the issue as unsatisfactory: Insufficient quality