hats-finance / AlephZeroAMM-0x0d88a9ece90994ecb3ba704730819d71c139f60f

Apache License 2.0
1 stars 0 forks source link

Owner tx will fail if the rewards amount < duration of the farming #45

Open hats-bug-reporter[bot] opened 9 months ago

hats-bug-reporter[bot] commented 9 months ago

Github username: @rodiontr Twitter username: -- Submission hash (on-chain): 0x5d2df285a3916c2d5140a328b4d7e96bd0063997ed04c121a19fd8411b7f0f61 Severity: high

Description: Description\

The user may be not able to deposit into a farm if his deposit amount is greater than the time interval of the farming.

Attack Scenario\

Let's say the owner wants to set 50_000 rewards for one day of farming equal to 86400 seconds. The problem is that the tx will revert due to the formula that makes the reward rate equal to 0 if the amount is less than duration of the farming.

Attachments

PoC:

#[drink::test]
fn rewards_fail() {

    // initialize the session
    let mut session: Session<MinimalRuntime> = Session::new().expect("Init new Session");

    // set up the necessary tokens (ICE(lp), WOOD(reward))
    let ice = setup_psp22(&mut session, ICE.to_string(), ICE.to_string(), BOB);
    let wood = setup_psp22(&mut session, WOOD.to_string(), WOOD.to_string(), BOB);

    // set up the farm with ICE as the pool token and WOOD as a reward token
    let farm = setup_farm(
        &mut session,
        ice.into(),
        vec![wood.into()],
        BOB,
    );

     // fetching up the timestamp
     let now =  get_timestamp(&mut session);
     set_timestamp(&mut session, now);

     // setting up start, end and the rewards amount
     let farm_start = now;
     let farm_end = farm_start + 86400;
     let rewards_amount = 50000;

     // deposit WOOD tokens into the farm
     increase_allowance(&mut session, wood.into(), farm.into(), rewards_amount, BOB);

    // starting farming
    let call_result = setup_farm_start(
        &mut session,
        &farm,
        farm_start,
        farm_end,
        vec![rewards_amount],
        BOB,
    );
    assert!(call_result.is_ok());

}

The test fails with the following error:

thread 'tests::rewards_fail' panicked at 'called `Result::unwrap()` on an `Err` value: AllRewardRatesZero', src/utils.rs:203:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
F
failures:

failures:
    tests::rewards_fail

However, the owner of the farm should be able to start the farm regardless of the duration.

You can see how this issue is not present anymore if the rewards > duration in seconds. They can be set, for example, to 100000 and the issue disappear:

#[drink::test]
fn rewards_fail() {

    // initialize the session
    let mut session: Session<MinimalRuntime> = Session::new().expect("Init new Session");

    // set up the necessary tokens (ICE(lp), WOOD(reward))
    let ice = setup_psp22(&mut session, ICE.to_string(), ICE.to_string(), BOB);
    let wood = setup_psp22(&mut session, WOOD.to_string(), WOOD.to_string(), BOB);

    // set up the farm with ICE as the pool token and WOOD as a reward token
    let farm = setup_farm(
        &mut session,
        ice.into(),
        vec![wood.into()],
        BOB,
    );

     // fetching up the timestamp
     let now =  get_timestamp(&mut session);
     set_timestamp(&mut session, now);

     // setting up start, end and the rewards amount
     let farm_start = now;
     let farm_end = farm_start + 86400;
     let rewards_amount = 100000;

     // deposit WOOD tokens into the farm
     increase_allowance(&mut session, wood.into(), farm.into(), rewards_amount, BOB);

    // starting farming
    let call_result = setup_farm_start(
        &mut session,
        &farm,
        farm_start,
        farm_end,
        vec![rewards_amount],
        BOB,
    );
    assert!(call_result.is_ok());

}

The output:

running 1 test
.
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.63s
deuszx commented 9 months ago

Thanks for the submission. Even though you've showed the problem manifesting in a different way, the underlying issue is the same as in https://github.com/hats-finance/AlephZeroAMM-0x0d88a9ece90994ecb3ba704730819d71c139f60f/issues/44 .

Or to put it differently - if you set your test on top of https://github.com/Cardinal-Cryptography/common-amm/pull/84 , it will not fail. That branch already includes the fix for the problem raised in #44.

deuszx commented 9 months ago

Thank you for the submission. After carefully reviewing it we've decided to mark it as INVALID.

PoC should refer to the actual point where the issue lies in and why. It's not enough to describe one of many scenarios where things break, without pointing out why.

We hope to see you in the future challenges of ink! codebase.