diff --git a/Cargo.toml b/Cargo.toml index 7bdd0f10..51f365e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ debug-assertions = true [profile.release] opt-level = "z" -overflow-checks = true +overflow-checks = true # DEV: Do not remove this check - doing so will create vulnerabilities debug = 0 strip = "symbols" debug-assertions = false diff --git a/README.md b/README.md index 9a76f7b4..3a0f28c2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ This repository contains the smart contacts for an implementation of the Blend P ## Documentation To learn more about the Blend Protocol, visit the docs: -* [Blend Docs](https://docs.blend.capital/) + +- [Blend Docs](https://docs.blend.capital/) ## Audits @@ -30,13 +31,21 @@ make test The `make` command creates an optimized and un-optimized set of WASM contracts. It's recommended to use the optimized version if deploying to a network. These can be found at the path: + ``` target/wasm32-unknown-unknown/optimized ``` + For help with deployment to a network, please visit the [Blend Utils](https://github.com/blend-capital/blend-utils) repo. +## Contributing + +Notes for contributors: + +- Under no circumstances should the "overflow-checks" flag be removed otherwise contract math will become unsafe + ## Community Links A set of links for various things in the community. Please submit a pull request if you would like a link included. -* [Blend Discord](https://discord.com/invite/a6CDBQQcjW) +- [Blend Discord](https://discord.com/invite/a6CDBQQcjW) diff --git a/test-suites/tests/test_overflow_flag.rs b/test-suites/tests/test_overflow_flag.rs new file mode 100644 index 00000000..e8be5865 --- /dev/null +++ b/test-suites/tests/test_overflow_flag.rs @@ -0,0 +1,100 @@ +#![cfg(test)] +use pool::Request; +use soroban_sdk::{testutils::Address as AddressTestTrait, vec, Address, Vec}; +use test_suites::{ + create_fixture_with_data, + test_fixture::{TokenIndex, SCALAR_7}, +}; + +#[test] +#[should_panic(expected = "Error(WasmVm, InvalidAction)")] +fn test_backstop_donate_overflow_panics() { + let fixture = create_fixture_with_data(true); + let pool_fixture = &fixture.pools[0]; + + // Create a user + let samwise = Address::generate(&fixture.env); + + fixture.tokens[TokenIndex::USDC].mint(&samwise, &(i128::MAX - 100)); + + // donate tokens + fixture + .backstop + .donate_usdc(&samwise, &pool_fixture.pool.address, &(i128::MAX - 100)); + fixture.tokens[TokenIndex::USDC].mint(&samwise, &(500)); + fixture.tokens[TokenIndex::USDC].burn(&fixture.backstop.address, &500); + fixture + .backstop + .donate_usdc(&samwise, &pool_fixture.pool.address, &201); +} + +// This test ensures that an accessible underflow in the auction flow cannot be hit due to the overflow-checks flag being set +// Without this flag set, filling an auction on the same block it's started would cause an underflow +#[test] +#[should_panic(expected = "Error(WasmVm, InvalidAction)")] +fn test_auction_underflow_panics() { + let fixture = create_fixture_with_data(true); + let frodo = fixture.users.get(0).unwrap(); + let pool_fixture = &fixture.pools[0]; + + // Create a user + let samwise = Address::generate(&fixture.env); //sam will be supplying XLM and borrowing STABLE + + // Mint users tokens + fixture.tokens[TokenIndex::XLM].mint(&samwise, &(500_000 * SCALAR_7)); + + // Supply and borrow sam tokens + let sam_requests: Vec = vec![ + &fixture.env, + Request { + request_type: 2, + address: fixture.tokens[TokenIndex::XLM].address.clone(), + amount: 6_000 * SCALAR_7, + }, + Request { + request_type: 4, + address: fixture.tokens[TokenIndex::STABLE].address.clone(), + amount: 200 * 10i128.pow(6), + }, + ]; + pool_fixture + .pool + .submit(&samwise, &samwise, &samwise, &sam_requests); + + //tank xlm price + fixture.oracle.set_price_stable(&vec![ + &fixture.env, + 1000_0000000, // eth + 1_0000000, // usdc + 0_0000100, // xlm + 1_0000000, // stable + ]); + + // liquidate user + let liq_pct = 100; + let auction_data_2 = pool_fixture + .pool + .new_liquidation_auction(&samwise, &liq_pct); + + let usdc_bid_amount = auction_data_2 + .bid + .get_unchecked(fixture.tokens[TokenIndex::STABLE].address.clone()); + + //fill user liquidation + let fill_requests = vec![ + &fixture.env, + Request { + request_type: 6, + address: samwise.clone(), + amount: 1, + }, + Request { + request_type: 5, + address: fixture.tokens[TokenIndex::STABLE].address.clone(), + amount: usdc_bid_amount, + }, + ]; + pool_fixture + .pool + .submit(&frodo, &frodo, &frodo, &fill_requests); +}