diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a4abb26e..8f5e1018 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @FuelLabs/application-dev +* @FuelLabs/swayex diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5b25f97c..b2cba484 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -35,3 +35,4 @@ Closes #\ - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. +- [ ] I have updated the changelog to reflect the changes on this PR. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07d2b6a1..9fedbb14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,10 +48,10 @@ jobs: run: cargo fmt --manifest-path tests/Cargo.toml --verbose --check - name: Build All Libs - run: forc build --path libs --release + run: forc build --path libs --release --locked - name: Build All Tests - run: forc build --path tests --release + run: forc build --path tests --release --locked - name: Cargo Test sway-lib run: | @@ -78,10 +78,10 @@ jobs: components: forc@${{ env.FORC_VERSION }}, fuel-core@${{ env.CORE_VERSION }} - name: Run Libs Tests - run: forc build --path libs --release && forc test --path libs + run: forc build --path libs --release --locked && forc test --path libs --locked - name: Run Tests Tests - run: forc build --path tests --release && forc test --path tests + run: forc build --path tests --release --locked && forc test --path tests --locked contributing-book: runs-on: ubuntu-latest @@ -165,7 +165,7 @@ jobs: run: cargo fmt --manifest-path examples/Cargo.toml --verbose --check - name: Build All Examples - run: forc build --path examples --release + run: forc build --path examples --release --locked - name: Cargo Test Examples run: | diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 564e7027..ef0b3769 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -33,26 +33,6 @@ jobs: destination_dir: contributing-book if: github.ref == 'refs/heads/master' - deploy-book: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Setup mdBook - uses: peaceiris/actions-mdbook@v1 - with: - mdbook-version: "0.4.15" - - - run: mdbook build ./docs/book - - - name: Deploy master - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/book/book - destination_dir: book - if: github.ref == 'refs/heads/master' - deploy-forc-doc-sway-libs: runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index ed3640cd..1eb35d0a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock -Forc.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..237c7f9c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,86 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [v0.23.0] + +### Added + +- [#259](https://github.com/FuelLabs/sway-libs/pull/259) Adds a new upgradability library, including associated tests and documentation. +- [#265](https://github.com/FuelLabs/sway-libs/pull/265) Adds the `SetMetadataEvent` and emits `SetMetadataEvent` when the `_set_metadata()` function is called. +- [#270](https://github.com/FuelLabs/sway-libs/pull/270) Adds `OrdEq` functionality to Signed Integers. +- [#272](https://github.com/FuelLabs/sway-libs/pull/272) Adds the `TryFrom` implementation from signed integers to unsigned integers. + +### Changed + +- [#265](https://github.com/FuelLabs/sway-libs/pull/265) Enables the metadata events now that the Rust SDK supports wrapped heap types. +- [#269](https://github.com/FuelLabs/sway-libs/pull/269) Hashes the string "admin" and with the bits of an Identity when creating a storage slot to storage an admin in the Admin Library. +- [#276](https://github.com/FuelLabs/sway-libs/pull/276) Prepares for v0.23.0 release. +- [#278](https://github.com/FuelLabs/sway-libs/pull/278) Deprecates the Fixed Point number library. + +### Fixed + +- [#258](https://github.com/FuelLabs/sway-libs/pull/258) Fixes incorrect instructions on how to run tests in README and docs hub. +- [#262](https://github.com/FuelLabs/sway-libs/pull/262) Fixes incorrect ordering comparison for IFP64, IFP128 and IFP256. +- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I256`'s returned bits. +- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Fixes `I128` and `I256`'s zero or "indent" value. +- [#268](https://github.com/FuelLabs/sway-libs/pull/268) Fixes subtraction involving negative numbers for `I8`, `I16`, `I32`, `I64`, `I128`, and `I256`. +- [#272](https://github.com/FuelLabs/sway-libs/pull/272) Fixes `From` implementations for Signed Integers with `TryFrom`. +- [#273](https://github.com/FuelLabs/sway-libs/pull/273) Fixes negative from implementations for Signed Integers. +- [#274](https://github.com/FuelLabs/sway-libs/pull/274) Fixes the `swap_configurables()` function to correctly handle the case where the bytecode is too large to fit in the buffer. +- [#275](https://github.com/FuelLabs/sway-libs/pull/275) Fixes an infinite loop in the Bytecode root library's `_compute_bytecode_root()` function. + +#### Breaking + +- [#263](https://github.com/FuelLabs/sway-libs/pull/263) Removes the `TwosComplement` trait in favor of `WrappingNeg`. + +The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types. + +Before: + +```sway +let my_i8 = i8::zero(); +let twos_complement = my_i8.twos_complement(); +``` + +After: + +```sway +let my_i8 = i8::zero(); +let wrapping_neg = my_i8.wrapping_neg(); +``` + +- [#272](https://github.com/FuelLabs/sway-libs/pull/272) The `From` implementation for all signed integers to their respective unsigned integer has been removed. The `TryFrom` implementation has been added in its place. + +Before: + +```sway +let my_i8: I8 = I8::from(1u8); +``` + +After: + +```sway +let my_i8: I8 = I8::try_from(1u8).unwrap(); +``` + +- [#273](https://github.com/FuelLabs/sway-libs/pull/273) The `neg_from` implementation for all signed integers has been removed. The `neg_try_from()` implementation has been added in its place. + +The following demonstrates the breaking change. While this example code uses the `I8` type, the same logic may be applied to the `I16`, `I32`, `I64`, `I128`, and `I256` types. + +Before: + +```sway +let my_negative_i8: I8 = I8::neg_from(1u8); +``` + +After: + +```sway +let my_negative_i8: I8 = I8::neg_try_from(1u8).unwrap(); +``` + +- [#278](https://github.com/FuelLabs/sway-libs/pull/278) Deprecates the Fixed Point number library. The Fixed Point number library is no longer available. diff --git a/Cargo.toml b/Cargo.toml index 00999e11..ffba569f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ [package] name = "sway-libs" -version = "0.22.0" +version = "0.23.0" edition = "2021" diff --git a/README.md b/README.md index ca331230..69f23263 100644 --- a/README.md +++ b/README.md @@ -22,18 +22,18 @@ ## Overview -The purpose of this repository is to contain libraries which users can import and use that are not part of the standard library. +The purpose of this repository is to contain libraries which users can import and use that are not part of the standard library. These libraries contain helper functions and other tools valuable to blockchain development. > **NOTE:** > Sway is a language under heavy development therefore the libraries may not be the most ergonomic. Over time they should receive updates / improvements in order to demonstrate how Sway can be used in real use cases. -## Sway Libs Book +## Sway Libs Docs Hub -Please refer to the [Sway Libs Book](https://fuellabs.github.io/sway-libs/book/index.html) for documentation for a general overview on Sway Libs and how to implement libraries. +Please refer to the [Sway Libs Docs Hub](https://docs.fuel.network/docs/sway-libs/) for documentation for a general overview on Sway Libs and how to implement libraries. -## Sway Docs +## Library Docs For implementation details on the libraries please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/). @@ -41,38 +41,44 @@ For implementation details on the libraries please see the [Sway Libs Docs](http #### Assets -- [Native Asset](https://fuellabs.github.io/sway-libs/book/asset/index.html) provides helper functions for the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md), [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md), and [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standards. +- [Native Asset](https://docs.fuel.network/docs/sway-libs/asset/) provides helper functions for the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standards. #### Access Control and Security -- [Ownership](https://fuellabs.github.io/sway-libs/book/ownership/index.html) is used to apply restrictions on functions such that only a **single** user may call them. -- [Admin](https://fuellabs.github.io/sway-libs/book/admin/index.html) is used to apply restrictions on functions such that only a select few users may call them like a whitelist. -- [Pausable](https://fuellabs.github.io/sway-libs/book/pausable/index.html) allows contracts to implement an emergency stop mechanism. -- [Reentrancy](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html) is used to detect and prevent reentrancy attacks. +- [Ownership](https://docs.fuel.network/docs/sway-libs/ownership/) is used to apply restrictions on functions such that only a **single** user may call them. +- [Admin](https://docs.fuel.network/docs/sway-libs/admin/) is used to apply restrictions on functions such that only a select few users may call them like a whitelist. +- [Pausable](https://docs.fuel.network/docs/sway-libs/pausable/) allows contracts to implement an emergency stop mechanism. +- [Reentrancy](https://docs.fuel.network/docs/sway-libs/reentrancy/) is used to detect and prevent reentrancy attacks. #### Cryptography -- [Bytecode](https://fuellabs.github.io/sway-libs/book/bytecode/index.html) is used for on-chain verification and computation of bytecode roots for contracts and predicates. -- [Merkle Proof](https://fuellabs.github.io/sway-libs/book/merkle/index.html) is used to verify Binary Merkle Trees computed off-chain. +- [Bytecode](https://docs.fuel.network/docs/sway-libs/bytecode/) is used for on-chain verification and computation of bytecode roots for contracts and predicates. +- [Merkle Proof](https://docs.fuel.network/docs/sway-libs/merkle/) is used to verify Binary Merkle Trees computed off-chain. #### Math -- [Fixed Point Number](https://fuellabs.github.io/sway-libs/book/fixed_point/index.html) is an interface to implement fixed-point numbers. -- [Signed Integers](https://fuellabs.github.io/sway-libs/book/signed_integers/index.html) is an interface to implement signed integers. +- [Signed Integers](https://docs.fuel.network/docs/sway-libs/queue/) is an interface to implement signed integers. + +> **NOTE:** +> The Fixed Point Number library has been deprecated pending a re-write. #### Data Structures -- [Queue](https://fuellabs.github.io/sway-libs/book/queue/index.html) is a linear data structure that provides First-In-First-Out (FIFO) operations. +- [Queue](https://docs.fuel.network/docs/sway-libs/queue/) is a linear data structure that provides First-In-First-Out (FIFO) operations. + +## Upgradability Libraries + +- [Upgradability](https://docs.fuel.network/docs/sway-libs/upgradability/) provides functions that can be used to implement contract upgrades via simple upgradable proxies. ## Using a library To import a library, the following dependency should be added to the project's `Forc.toml` file under `[dependencies]`. ```rust -sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.22.0" } +sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.23.0" } ``` -> **NOTE:** +> **NOTE:** > Be sure to set the tag to the latest release. You may then import your desired library in your Sway Smart Contract as so: @@ -87,26 +93,24 @@ For example, to import the `only_owner()` function use the following statement: use sway_libs::ownership::only_owner; ``` -For more information about implementation please refer to the [Sway Libs Book](https://fuellabs.github.io/sway-libs/book/index.html) +For more information about implementation please refer to the [Sway Libs Docs Hub](https://docs.fuel.network/docs/sway-libs/) ## Running Tests -There are two sets of tests that should be run: inline tests and sdk-harness tests. +There are two sets of tests that should be run: inline tests and sdk-harness tests. Please make sure you are using `forc v0.60.0` and `fuel-core v0.26.0`. You can check what version you are using by running the `fuelup show` command. -In order to run the inline tests, make sure you are in the `libs/` folder of this repository `sway-libs/libs/`. +Make sure you are in the source directory of this repository `sway-libs/`. -Run the tests: +Run the inline tests: ```bash -forc test +forc test --path libs --release --locked ``` -Once these tests have passed, make sure you are in the `tests/` folder of this repository `sway-libs/tests/`. - -Run the tests: +Once these tests have passed, run the sdk-harness tests: ```bash -forc test && cargo test +forc test --path tests --release --locked && cargo test --manifest-path tests/Cargo.toml ``` > **NOTE:** @@ -115,8 +119,8 @@ forc test && cargo test Any instructions related to using a specific library should be found within the README.md of that library. > **NOTE:** -> All projects currently use `forc v0.60.0`, `fuels-rs v0.62.0` and `fuel-core 0.26.0`. +> All projects currently use `forc v0.60.0`, `fuels-rs v0.62.0` and `fuel-core v0.26.0`. ## Contributing -Check out the [book](https://fuellabs.github.io/sway-libs/contributing-book/index.html) for more info! +Check out the [contributing book](https://fuellabs.github.io/sway-libs/contributing-book/index.html) for more info! diff --git a/docs/book/spell-check-custom-words.txt b/docs/book/spell-check-custom-words.txt index 192a3cee..d066d8e8 100644 --- a/docs/book/spell-check-custom-words.txt +++ b/docs/book/spell-check-custom-words.txt @@ -207,4 +207,6 @@ Enqueuing Dequeuing StorageMetadata functionly -verifiably \ No newline at end of file +verifiably +upgradable +upgradability \ No newline at end of file diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 1ea7dda8..499bdaa0 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -4,7 +4,6 @@ - [Getting Started](./getting_started/index.md) - [Running Tests](./getting_started/running_tests.md) -- [Libraries Overview](./libraries.md) - [Asset Library](./asset/index.md) - [Base](./asset/base.md) - [Supply](./asset/supply.md) @@ -15,6 +14,6 @@ - [Reentrancy Guard Library](./reentrancy/index.md) - [Bytecode Library](./bytecode/index.md) - [Merkle Library](./merkle/index.md) -- [Fixed Point Number Library](./fixed_point/index.md) - [Signed Integers Library](./signed_integers/index.md) - [Queue Library](./queue/index.md) +- [Upgradability](./upgradability/index.md) diff --git a/docs/book/src/asset/base.md b/docs/book/src/asset/base.md index eb78379e..227779ba 100644 --- a/docs/book/src/asset/base.md +++ b/docs/book/src/asset/base.md @@ -4,9 +4,9 @@ For implementation details on the Asset Library base functionality please see th ## Importing the Asset Library Base Functionality -In order to use the Asset Library, Sway Libs and [Sway Standards](https://github.com/FuelLabs/sway-standards) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://github.com/FuelLabs/sway-standards). +In order to use the Asset Library, Sway Libs and [Sway Standards](https://docs.fuel.network/docs/sway-standards/) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://docs.fuel.network/docs/sway-standards/#using-a-standard). -To import the Asset Library Base Functionality and [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) Standard to your Sway Smart Contract, add the following to your Sway file: +To import the Asset Library Base Functionality and [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard to your Sway Smart Contract, add the following to your Sway file: ```sway {{#include ../../../../examples/asset/base_docs/src/main.sw:import}} @@ -14,7 +14,7 @@ To import the Asset Library Base Functionality and [SRC-20](https://github.com/F ## Integration with the SRC-20 Standard -The [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) definition states that the following abi implementation is required for any Native Asset on Fuel: +The [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) definition states that the following abi implementation is required for any Native Asset on Fuel: ```sway {{#include ../../../../examples/asset/base_docs/src/main.sw:src20_abi}} @@ -28,7 +28,7 @@ The Asset Library has the following complimentary functions for each function in - `_symbol()` - `_decimals()` -The following ABI and functions are also provided to set your [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) standard storage values: +The following ABI and functions are also provided to set your [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard storage values: ```sway {{#include ../../../../examples/asset/base_docs/src/main.sw:set_attributes}} @@ -42,7 +42,7 @@ The following ABI and functions are also provided to set your [SRC-20](https://g ## Setting Up Storage -Once imported, the Asset Library's base functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) standard. +Once imported, the Asset Library's base functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard. ```sway {{#include ../../../../examples/asset/base_docs/src/main.sw:src20_storage}} @@ -50,7 +50,7 @@ Once imported, the Asset Library's base functionality should be available. To us ## Implementing the SRC-20 Standard with the Asset Library -To use the Asset Library's base functionly, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) standard in combination with the Asset Library with no user defined restrictions or custom functionality. +To use the Asset Library's base functionly, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. ```sway {{#include ../../../../examples/asset/basic_src20/src/main.sw:basic_src20}} diff --git a/docs/book/src/asset/index.md b/docs/book/src/asset/index.md index 60bd31b4..c9c1f6d2 100644 --- a/docs/book/src/asset/index.md +++ b/docs/book/src/asset/index.md @@ -1,17 +1,17 @@ # Asset Library -The Asset Library provides basic helper functions for the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md), [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md), and the [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md). It is intended to make development of Native Assets using Sway quick and easy while following the standard's specifications. +The Asset Library provides basic helper functions for the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and the [SRC-7; Arbitrary Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/). It is intended to make development of Native Assets using Sway quick and easy while following the standard's specifications. For implementation details on the Asset Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/index.html). ## [SRC-20 Functionality](./base.md) -The Base or core of any Asset on the Fuel Network must follow the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md). The Asset Library's [Base](./base.md) section supports the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md)'s implementation. +The Base or core of any Asset on the Fuel Network must follow the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/). The Asset Library's [Base](./base.md) section supports the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/)'s implementation. ## [SRC-3 Functionality](supply.md) -The [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) prescribes an ABI for how Native Assets on the Fuel Network are minted and burned. The Asset Library's [supply](./supply.md) section supports the [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md)'s implementation. +The [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) prescribes an ABI for how Native Assets on the Fuel Network are minted and burned. The Asset Library's [supply](./supply.md) section supports the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/)'s implementation. ## [SRC-7 Functionality](./metadata.md) -The [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) prescribes an ABI for metadata associated with Native Assets on the Fuel Network. The Asset Library's [metadata](./metadata.md) section supports the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md)'s implementation. +The [SRC-7; Arbitrary Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) prescribes an ABI for metadata associated with Native Assets on the Fuel Network. The Asset Library's [metadata](./metadata.md) section supports the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/)'s implementation. diff --git a/docs/book/src/asset/metadata.md b/docs/book/src/asset/metadata.md index 9a63337c..ccd442ff 100644 --- a/docs/book/src/asset/metadata.md +++ b/docs/book/src/asset/metadata.md @@ -4,9 +4,9 @@ For implementation details on the Asset Library metadata functionality please se ## Importing the Asset Library Metadata Functionality -In order to use the Asset Library, Sway Libs and [Sway Standards](https://github.com/FuelLabs/sway-standards) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://github.com/FuelLabs/sway-standards). +In order to use the Asset Library, Sway Libs and [Sway Standards](https://docs.fuel.network/docs/sway-standards/) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://docs.fuel.network/docs/sway-standards/#using-a-standard). -To import the Asset Library Base Functionality and [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) Standard to your Sway Smart Contract, add the following to your Sway file: +To import the Asset Library Base Functionality and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard to your Sway Smart Contract, add the following to your Sway file: ```sway {{#include ../../../../examples/asset/metadata_docs/src/main.sw:import}} @@ -14,17 +14,17 @@ To import the Asset Library Base Functionality and [SRC-7](https://github.com/Fu ## Integration with the SRC-7 Standard -The [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) definition states that the following abi implementation is required for any Native Asset on Fuel: +The [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) definition states that the following abi implementation is required for any Native Asset on Fuel: ```sway {{#include ../../../../examples/asset/metadata_docs/src/main.sw:src7_abi}} ``` -The Asset Library has the following complimentary data type for the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standard: +The Asset Library has the following complimentary data type for the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard: - `StorageMetadata` -The following additional functionality for the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md)'s `Metadata` type is provided: +The following additional functionality for the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/)'s `Metadata` type is provided: - `as_string()` - `is_string()` @@ -37,7 +37,7 @@ The following additional functionality for the [SRC-7](https://github.com/FuelLa ## Setting Up Storage -Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standard. +Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard. ```sway {{#include ../../../../examples/asset/metadata_docs/src/main.sw:src7_storage}} @@ -47,7 +47,7 @@ Once imported, the Asset Library's metadata functionality should be available. T ### Setting Metadata -To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by the Asset Library. Be sure to follow the [SRC-9](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-9.md) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata. +To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by the Asset Library. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata. ```sway {{#include ../../../../examples/asset/setting_src7_attributes/src/main.sw:setting_src7_attributes}} @@ -57,7 +57,7 @@ To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by th ### Implementing the SRC-7 Standard with StorageMetadata -To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId`. The example below shows the implementation of the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standard in combination with the Asset Library's `StorageMetadata` type with no user defined restrictions or custom functionality. +To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId`. The example below shows the implementation of the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type with no user defined restrictions or custom functionality. ```sway {{#include ../../../../examples/asset/basic_src7/src/main.sw:basic_src7}} @@ -65,7 +65,7 @@ To use the `StorageMetadata` type, simply get the stored metadata with the assoc ## Using the `Metadata` Extensions -The `Metadata` type defined by the [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standard can be one of 4 states: +The `Metadata` type defined by the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard can be one of 4 states: ```sway pub enum Metadata { diff --git a/docs/book/src/asset/supply.md b/docs/book/src/asset/supply.md index b503ab05..1d63c298 100644 --- a/docs/book/src/asset/supply.md +++ b/docs/book/src/asset/supply.md @@ -4,9 +4,9 @@ For implementation details on the Asset Library supply functionality please see ## Importing the Asset Library Supply Functionality -In order to use the Asset Library, Sway Libs and [Sway Standards](https://github.com/FuelLabs/sway-standards) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://github.com/FuelLabs/sway-standards). +In order to use the Asset Library, Sway Libs and [Sway Standards](https://docs.fuel.network/docs/sway-standards/) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://docs.fuel.network/docs/sway-standards/#using-a-standard). -To import the Asset Library Supply Functionality and [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) Standard to your Sway Smart Contract, add the following to your Sway file: +To import the Asset Library Supply Functionality and [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard to your Sway Smart Contract, add the following to your Sway file: ```sway {{#include ../../../../examples/asset/supply_docs/src/main.sw:import}} @@ -14,7 +14,7 @@ To import the Asset Library Supply Functionality and [SRC-3](https://github.com/ ## Integration with the SRC-3 Standard -The [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) definition states that the following abi implementation is required for any Native Asset on Fuel which mints and burns tokens: +The [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) definition states that the following abi implementation is required for any Native Asset on Fuel which mints and burns tokens: ```sway {{#include ../../../../examples/asset/supply_docs/src/main.sw:src3_abi}} @@ -29,7 +29,7 @@ The Asset Library has the following complimentary functions for each function in ## Setting Up Storage -Once imported, the Asset Library's supply functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) standard. +Once imported, the Asset Library's supply functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard. ```sway {{#include ../../../../examples/asset/supply_docs/src/main.sw:src3_storage}} @@ -37,7 +37,7 @@ Once imported, the Asset Library's supply functionality should be available. To ## Implementing the SRC-3 Standard with the Asset Library -To use a base function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library;s supply functionality to ensure only a single user has permissions to mint an Asset. +To use a base function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library;s supply functionality to ensure only a single user has permissions to mint an Asset. ```sway {{#include ../../../../examples/asset/basic_src3/src/main.sw:basic_src3}} diff --git a/docs/book/src/fixed_point/index.md b/docs/book/src/fixed_point/index.md deleted file mode 100644 index 0ce58768..00000000 --- a/docs/book/src/fixed_point/index.md +++ /dev/null @@ -1,87 +0,0 @@ -# Fixed Point Number Library - -The Fixed Point Number Library provides a library to use fixed-point numbers in Sway. It has 3 distinct unsigned types: `UFP32`, `UFP64` and `UFP128` as well as 3 signed types `IFP64`, `IFP128` and `IFP256`. These types are stack allocated. - -This type is stored as a `u32`, `u64` or `U128` under the hood. Therefore the size can be known at compile time and the length is static. - -For implementation details on the Fixed Point Number Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/fixed_point/index.html). - -## Importing the Fixed Point Number Library - -In order to use the Fixed Point Number Library, Sway Libs must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). - -To import the Fixed Point Number Library to your Sway Smart Contract, add the following to your Sway file: - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:import}} -``` - -## Supported Fixed Point Numbers - -### Signed Fixed Point Numbers - -We currently support the following signed Fixed Point numbers: - -- `IFP64` -- `IFP128` -- `IFP256` - -In order to use the `IFP64`, `IFP128` or `IFP256` types, import them into your Sway project like so: - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:import_ifp}} -``` - -### Unsigned Fixed Point Numbers - -We currently support the following unsigned Fixed Point numbers: - -- `UFP32` -- `UFP64` -- `UFP128` - -In order to use the `UFP32`, `UFP64` or `UFP128` types, import them into your Sway project like so: - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:import_ufp}} -``` - -## Basic Functionality - -### Instantiating a New Fixed Point Number - -Once imported, any signed or unsigned Fixed Point number type can be instantiated by defining a new variable and calling the `from` function. - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:instantiating_ufp}} -``` - -### Basic mathematical Functions - -Basic arithmetic operations are working as usual. - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:mathematical_ops}} -``` - -### Advanced mathematical Functions Supported - -We currently support the following advanced mathematical functions: - -#### Exponential - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:exponential}} -``` - -#### Square Root - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:square_root}} -``` - -#### Power - -```sway -{{#include ../../../../examples/fixed_point/src/main.sw:power}} -``` diff --git a/docs/book/src/getting_started/index.md b/docs/book/src/getting_started/index.md index 32d64253..ee3c903a 100644 --- a/docs/book/src/getting_started/index.md +++ b/docs/book/src/getting_started/index.md @@ -5,7 +5,7 @@ To import any library, the following dependency should be added to the project's `Forc.toml` file under `[dependencies]`. ```sway -sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.22.0" } +sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.23.0" } ``` For reference, here is a complete `Forc.toml` file: @@ -18,7 +18,7 @@ license = "Apache-2.0" name = "MyProject" [dependencies] -sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.22.0" } +sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.23.0" } ``` > **NOTE:** Be sure to set the tag to the latest release. @@ -68,6 +68,6 @@ impl Pausable for Contract { } ``` -Any instructions related to using a specific library should be found within the [libraries](../libraries.md) section of the Sway Libs Book. +Any instructions related to using a specific library should be found within the [libraries](../index.md) section of the Sway Libs Book. For implementation details on the libraries please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/). diff --git a/docs/book/src/getting_started/running_tests.md b/docs/book/src/getting_started/running_tests.md index dc61441f..5bea15e2 100644 --- a/docs/book/src/getting_started/running_tests.md +++ b/docs/book/src/getting_started/running_tests.md @@ -1,21 +1,19 @@ # Running Tests -There are two sets of tests that should be run: inline tests and sdk-harness tests. +There are two sets of tests that should be run: inline tests and sdk-harness tests. Please make sure you are using `forc v0.60.0` and `fuel-core v0.26.0`. You can check what version you are using by running the `fuelup show` command. -In order to run the inline tests, make sure you are in the `libs/` folder of this repository `sway-libs/libs/`. +Make sure you are in the source directory of this repository `sway-libs/`. -Run the tests: +Run the inline tests: ```bash -forc test +forc test --path libs --release --locked ``` -Once these tests have passed, make sure you are in the `tests/` folder of this repository `sway-libs/tests/`. - -Run the tests: +Once these tests have passed, run the sdk-harness tests: ```bash -forc test && cargo test +forc test --path tests --release --locked && cargo test --manifest-path tests/Cargo.toml ``` > **NOTE:** diff --git a/docs/book/src/index.md b/docs/book/src/index.md index 77466337..b5fa21ae 100644 --- a/docs/book/src/index.md +++ b/docs/book/src/index.md @@ -2,7 +2,70 @@ The purpose of Sway Libraries is to contain libraries which users can import and use that are not part of the standard library. -These libraries contain helper functions and other tools valuable to blockchain development. +There are several types of libraries that Sway Libs encompases. These include libraries that provide convenience functions, [Sway-Standards](https://github.com/FuelLabs/sway-standards) supporting libraries, data type libraries, security functionality libraries, and other tools valuable to blockchain development. -> **NOTE:** -> Sway is a language under heavy development therefore the libraries may not be the most ergonomic. Over time they should receive updates / improvements in order to demonstrate how Sway can be used in real use cases. +For implementation details on the libraries please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/). + +## Assets Libraries + +Asset Libraries are any libraries that use [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network. + +### [Asset Library](./asset/index.md) + +The [Asset](./asset/index.md) Library provides helper functions for the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standards. + +## Access Control and Security Libraries + +Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts. + +### [Ownership Library](./ownership/index.md) + +The [Ownership](./ownership/index.md) Library is used to apply restrictions on functions such that only a **single** user may call them. + +### [Admin Library](./admin/index.md) + +The [Admin](./admin/index.md) Library is used to apply restrictions on functions such that only a select few users may call them like a whitelist. + +### [Pausable Library](./pausable/index.md) + +The [Pausable](./pausable/index.md) Library allows contracts to implement an emergency stop mechanism. + +### [Reentrancy Guard Library](./reentrancy/index.md) + +The [Reentrancy Guard](./reentrancy/index.md) Library is used to detect and prevent reentrancy attacks. + +## Cryptography Libraries + +Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides. + +### [Bytecode Library](./bytecode/index.md) + +The [Bytecode](./bytecode/index.md) Library is used for on-chain verification and computation of bytecode roots for contracts and predicates. + +### [Merkle Library](./merkle/index.md) + +The [Merkle Proof](./merkle/index.md) Library is used to verify Binary Merkle Trees computed off-chain. + +## Math Libraries + +Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope. + +### [Signed Integers](./signed_integers/index.md) + +The [Signed Integers](./signed_integers/index.md) Library is an interface to implement signed integers. + +## Data Structures Libraries + +Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts. + +### [Queue](./queue/index.md) + +The [Queue](./queue/index.md) Library is a linear data structure that provides First-In-First-Out (FIFO) operations. + +## Upgradability Libraries + +Upgradability Libraries are libraries which provide functions to implement contract upgrades. + +### [Upgradability](./upgradability/index.md) + +The [Upgradability](./upgradability/index.md) Library provides functions that can be used to implement contract upgrades via simple upgradable proxies. diff --git a/docs/book/src/libraries.md b/docs/book/src/libraries.md deleted file mode 100644 index 6e130d79..00000000 --- a/docs/book/src/libraries.md +++ /dev/null @@ -1,65 +0,0 @@ -# Libraries - -There are several types of libraries that Sway Libs encompases. These include libraries that provide convenience functions, standards supporting libraries, data type libraries, security functionality libraries. - -For implementation details on the libraries please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/). - -## Assets Libraries - -Asset Libraries are any libraries that use [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network. - -### [Asset Library](./asset/index.md) - -The [Asset](./asset/index.md) Library provides helper functions for the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md), [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md), and [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) standards. - -## Access Control and Security Libraries - -Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts. - -### [Ownership Library](./ownership/index.md) - -The [Ownership](./ownership/index.md) Library is used to apply restrictions on functions such that only a **single** user may call them. - -### [Admin Library](./admin/index.md) - -The [Admin](./admin/index.md) Library is used to apply restrictions on functions such that only a select few users may call them like a whitelist. - -### [Pausable Library](./pausable/index.md) - -The [Pausable](./pausable/index.md) Library allows contracts to implement an emergency stop mechanism. - -### [Reentrancy Guard Library](./reentrancy/index.md) - -The [Reentrancy Guard](./reentrancy/index.md) Library is used to detect and prevent reentrancy attacks. - -## Cryptography Libraries - -Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides. - -### [Bytecode Library](./bytecode/index.md) - -The [Bytecode](./bytecode/index.md) Library is used for on-chain verification and computation of bytecode roots for contracts and predicates. - -### [Merkle Library](./merkle/index.md) - -The [Merkle Proof](./merkle/index.md) Library is used to verify Binary Merkle Trees computed off-chain. - -## Math Libraries - -Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope. - -### [Fixed Point Number Library](./fixed_point/index.md) - -The [Fixed Point Number](./fixed_point/index.md) Library is an interface to implement fixed-point numbers. - -### [Signed Integers](./signed_integers/index.md) - -The [Signed Integers](./signed_integers/index.md) Library is an interface to implement signed integers. - -## Data Structures Libraries - -Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts. - -### [Queue](./queue/index.md) - -The [Queue](./queue/index.md) Library is a linear data structure that provides First-In-First-Out (FIFO) operations. diff --git a/docs/book/src/ownership/index.md b/docs/book/src/ownership/index.md index 26157611..d652efcd 100644 --- a/docs/book/src/ownership/index.md +++ b/docs/book/src/ownership/index.md @@ -6,9 +6,9 @@ For implementation details on the Ownership Library please see the [Sway Libs Do ## Importing the Ownership Library -In order to use the Ownership library, Sway Libs and [Sway Standards](https://github.com/FuelLabs/sway-standards) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://github.com/FuelLabs/sway-standards). +In order to use the Ownership library, Sway Libs and [Sway Standards](https://docs.fuel.network/docs/sway-standards/) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://docs.fuel.network/docs/sway-standards/#using-a-standard). -To import the Ownership Library and [SRC-5](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-5.md) Standard to your Sway Smart Contract, add the following to your Sway file: +To import the Ownership Library and [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard to your Sway Smart Contract, add the following to your Sway file: ```sway {{#include ../../../../examples/ownership/src/main.sw:import}} @@ -16,7 +16,7 @@ To import the Ownership Library and [SRC-5](https://github.com/FuelLabs/sway-sta ## Integrating the Ownership Library into the SRC-5 Standard -To implement the [SRC-5](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-5.md) standard with the Ownership library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-5 standard. +To implement the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) standard with the Ownership library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-5 standard. ```sway {{#include ../../../../examples/ownership/src/main.sw:integrate_with_src5}} diff --git a/docs/book/src/upgradability/index.md b/docs/book/src/upgradability/index.md new file mode 100644 index 00000000..bb070909 --- /dev/null +++ b/docs/book/src/upgradability/index.md @@ -0,0 +1,63 @@ +# Upgradability Library + +The Upgradability Library provides functions that can be used to implement contract upgrades via simple upgradable proxies. The Upgradability Library implements the required and optional functionality from [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradable-proxies/) as well as additional functionality for ownership of the proxy contract. + +For implementation details on the Upgradability Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/upgradability/index.html). + +## Importing the Upgradability Library + +In order to use the Upgradability library, Sway Libs and [Sway Standards](https://docs.fuel.network/docs/sway-standards/) must be added to the `Forc.toml` file and then imported into your Sway project. To add Sway Libs as a dependency to the `Forc.toml` file in your project please see the [Getting Started](../getting_started/index.md). To add Sway Standards as a dependency please see the [Sway Standards Book](https://docs.fuel.network/docs/sway-standards/#using-a-standard). + +To import the Upgradability Library and [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradable-proxies/) Standard to your Sway Smart Contract, add the following to your Sway file: + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:import}} +``` + +## Integrating the Upgradability Library into the SRC-14 Standard + +To implement the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradable-proxies/) standard with the Upgradability library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-14 standard. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:integrate_with_src14}} +``` + +> **NOTE** An initialization method must be implemented to initialize the proxy target or proxy owner. + +## Basic Functionality + +### Setting and getting a Proxy Target + +Once imported, the Upgradability Library's functions will be available. Use them to change the proxy target for your contract by calling the `set_proxy_target()` function. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:set_proxy_target}} +``` + +Use the `proxy_target()` method to get the current proxy target. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:proxy_target}} +``` + +### Setting and getting a Proxy Owner + +To change the proxy target for your contract use the `set_proxy_owner()` function. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:set_proxy_owner}} +``` + +Use the `proxy_owner()` method to get the current proxy owner. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:proxy_owner}} +``` + +### Proxy access control + +To restrict a function to only be callable by the proxy's owner, call the `only_proxy_owner()` function. + +```sway +{{#include ../../../../examples/upgradability/src/main.sw:only_proxy_owner}} +``` diff --git a/examples/Forc.lock b/examples/Forc.lock new file mode 100644 index 00000000..95cde592 --- /dev/null +++ b/examples/Forc.lock @@ -0,0 +1,181 @@ +[[package]] +name = "admin_examples" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "base_docs" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "basic_src20" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "basic_src3" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "basic_src7" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "bytecode_examples" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "core" +source = "path+from-root-E19CE48B3E858B72" + +[[package]] +name = "merkle_examples" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "metadata_docs" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "ownership_examples" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "pausable_example" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "pausable_with_ownership_example" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "queue_examples" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "reentrancy_examples" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "setting_src20_attributes" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "setting_src7_attributes" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "signed_integers_examples" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "standards" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18" +dependencies = ["std"] + +[[package]] +name = "standards" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.1#e2d5ac40a1d11a9e38e0a662d35141076515319f" +dependencies = ["std"] + +[[package]] +name = "std" +source = "git+https://github.com/fuellabs/sway?tag=v0.60.0#2f0392ee35a1e4dd80bd8034962d5b4083dfb8b6" +dependencies = ["core"] + +[[package]] +name = "supply_docs" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "sway_libs" +source = "path+from-root-9E88A97493D252A9" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", +] + +[[package]] +name = "upgradability_examples" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.1#e2d5ac40a1d11a9e38e0a662d35141076515319f", + "std", + "sway_libs", +] diff --git a/examples/Forc.toml b/examples/Forc.toml index fe7092f7..89770e88 100644 --- a/examples/Forc.toml +++ b/examples/Forc.toml @@ -10,7 +10,6 @@ members = [ "./asset/setting_src20_attributes", "./asset/supply_docs", "./bytecode", - "./fixed_point", "./merkle", "./ownership", "./pausable/pausable", @@ -18,4 +17,5 @@ members = [ "./queue", "./reentrancy", "./signed_integers", + "./upgradability", ] diff --git a/examples/fixed_point/src/main.sw b/examples/fixed_point/src/main.sw deleted file mode 100644 index ddd32da1..00000000 --- a/examples/fixed_point/src/main.sw +++ /dev/null @@ -1,60 +0,0 @@ -library; - -// ANCHOR: import -use sway_libs::fixed_point::*; -// ANCHOR_END: import - -// ANCHOR: import_ifp -use sway_libs::fixed_point::{ifp128::IFP128, ifp256::IFP256, ifp64::IFP64,}; -// ANCHOR_END: import_ifp - -// ANCHOR: import_ufp -use sway_libs::fixed_point::{ufp128::UFP128, ufp32::UFP32, ufp64::UFP64,}; -// ANCHOR_END: import_ufp - -fn instantiating_ufp() { - // ANCHOR: instantiating_ufp - let mut ufp32_value = UFP32::from(0u32); - let mut ufp64_value = UFP64::from(0u64); - let mut ufp128_value = UFP128::from((0u64, 0u64)); - // ANCHOR_END: instantiating_ufp -} - -// ANCHOR: mathematical_ops -fn add_ufp(val1: UFP64, val2: UFP64) { - let result: UFP64 = val1 + val2; -} - -fn subtract_ufp(val1: UFP64, val2: UFP64) { - let result: UFP64 = val1 - val2; -} - -fn multiply_ufp(val1: UFP64, val2: UFP64) { - let result: UFP64 = val1 * val2; -} - -fn divide_ufp(val1: UFP64, val2: UFP64) { - let result: UFP64 = val1 / val2; -} -// ANCHOR_END: mathematical_ops - -fn exponential() { - // ANCHOR: exponential - let ten = UFP64::from_uint(10); - let res = UFP64::exp(ten); - // ANCHOR_END: exponential -} - -fn square_root() { - // ANCHOR: square_root - let ufp64_169 = UFP64::from_uint(169); - let res = UFP64::sqrt(ufp64_169); - // ANCHOR_END: square_root -} - -fn power() { - // ANCHOR: power - let five = UFP64::from_uint(5); - let res = five.pow(3u32); - // ANCHOR_END: power -} diff --git a/examples/fixed_point/Forc.toml b/examples/upgradability/Forc.toml similarity index 55% rename from examples/fixed_point/Forc.toml rename to examples/upgradability/Forc.toml index 4b28498e..0859e406 100644 --- a/examples/fixed_point/Forc.toml +++ b/examples/upgradability/Forc.toml @@ -2,7 +2,8 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "fixed_point_examples" +name = "upgradability_examples" [dependencies] +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.1" } sway_libs = { path = "../../libs" } diff --git a/examples/upgradability/src/main.sw b/examples/upgradability/src/main.sw new file mode 100644 index 00000000..26ebf40f --- /dev/null +++ b/examples/upgradability/src/main.sw @@ -0,0 +1,73 @@ +contract; + +// ANCHOR: import +use sway_libs::upgradability::*; +use standards::{src14::*, src5::*}; +// ANCHOR_END: import + +// ANCHOR: integrate_with_src14 +use sway_libs::upgradability::{_proxy_owner, _proxy_target, _set_proxy_target}; +use standards::{src14::{SRC14, SRC14Extension}, src5::State}; + +#[namespace(SRC14)] +storage { + // target is at sha256("storage_SRC14_0") + target: Option = None, + proxy_owner: State = State::Uninitialized, +} + +impl SRC14 for Contract { + #[storage(read, write)] + fn set_proxy_target(new_target: ContractId) { + _set_proxy_target(new_target); + } + + #[storage(read)] + fn proxy_target() -> Option { + _proxy_target() + } +} + +impl SRC14Extension for Contract { + #[storage(read)] + fn proxy_owner() -> State { + _proxy_owner(storage.proxy_owner) + } +} +// ANCHOR_END: integrate_with_src14 + +// ANCHOR: set_proxy_target +#[storage(read, write)] +fn set_proxy_target(new_target: ContractId) { + _set_proxy_target(new_target); +} +// ANCHOR_END: set_proxy_target + +// ANCHOR: proxy_target +#[storage(read)] +fn proxy_target() -> Option { + _proxy_target() +} +// ANCHOR_END: proxy_target + +// ANCHOR: set_proxy_owner +#[storage(write)] +fn set_proxy_owner(new_proxy_owner: State) { + _set_proxy_owner(new_proxy_owner, storage.proxy_owner); +} +// ANCHOR_END: set_proxy_owner + +// ANCHOR: proxy_owner +#[storage(read)] +fn proxy_owner() -> State { + _proxy_owner(storage.proxy_owner) +} +// ANCHOR_END: proxy_owner + +// ANCHOR: only_proxy_owner +#[storage(read)] +fn only_proxy_owner_may_call() { + only_proxy_owner(storage.proxy_owner); + // Only the proxy's owner may reach this line. +} +// ANCHOR_END: only_proxy_owner diff --git a/libs/Forc.lock b/libs/Forc.lock new file mode 100644 index 00000000..0c2855ba --- /dev/null +++ b/libs/Forc.lock @@ -0,0 +1,21 @@ +[[package]] +name = "core" +source = "path+from-root-E19CE48B3E858B72" + +[[package]] +name = "standards" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18" +dependencies = ["std"] + +[[package]] +name = "std" +source = "git+https://github.com/fuellabs/sway?tag=v0.60.0#2f0392ee35a1e4dd80bd8034962d5b4083dfb8b6" +dependencies = ["core"] + +[[package]] +name = "sway_libs" +source = "member" +dependencies = [ + "standards", + "std", +] diff --git a/libs/src/admin.sw b/libs/src/admin.sw index e4e7745d..3e6b401e 100644 --- a/libs/src/admin.sw +++ b/libs/src/admin.sw @@ -1,12 +1,11 @@ library; -// TODO: Make this private when https://github.com/FuelLabs/sway/issues/5765 is resolved. pub mod errors; use ::admin::errors::AdminError; use ::ownership::{_owner, only_owner}; use standards::src5::State; -use std::{auth::msg_sender, storage::storage_api::clear,}; +use std::{auth::msg_sender, hash::{Hash, sha256}, storage::storage_api::clear,}; // Sets a new administrator. /// @@ -37,7 +36,8 @@ use std::{auth::msg_sender, storage::storage_api::clear,}; pub fn add_admin(new_admin: Identity) { only_owner(); - let admin_key = StorageKey::::new(new_admin.bits(), 0, new_admin.bits()); + let key_digest = sha256(("admin", new_admin.bits())); + let admin_key = StorageKey::::new(key_digest, 0, key_digest); admin_key.write(new_admin); } @@ -70,7 +70,8 @@ pub fn add_admin(new_admin: Identity) { pub fn revoke_admin(old_admin: Identity) { only_owner(); - let admin_key = StorageKey::::new(old_admin.bits(), 0, old_admin.bits()); + let key_digest = sha256(("admin", old_admin.bits())); + let admin_key = StorageKey::::new(key_digest, 0, key_digest); let _ = admin_key.clear(); } @@ -99,7 +100,8 @@ pub fn revoke_admin(old_admin: Identity) { /// ``` #[storage(read)] pub fn is_admin(admin: Identity) -> bool { - let admin_key = StorageKey::::new(admin.bits(), 0, admin.bits()); + let key_digest = sha256(("admin", admin.bits())); + let admin_key = StorageKey::::new(key_digest, 0, key_digest); match admin_key.try_read() { Some(identity) => { admin == identity diff --git a/libs/src/asset/metadata.sw b/libs/src/asset/metadata.sw index ae3a4bd7..4af81c82 100644 --- a/libs/src/asset/metadata.sw +++ b/libs/src/asset/metadata.sw @@ -2,6 +2,7 @@ library; use standards::src7::Metadata; use std::{ + auth::msg_sender, bytes::Bytes, hash::{ Hash, @@ -18,6 +19,18 @@ use std::{ string::String, }; +/// The event emitted when metadata is set via the `_set_metadata()` function. +pub struct SetMetadataEvent { + /// The asset for which metadata is set. + asset: AssetId, + /// The `Identity` of the caller that set the metadata. + sender: Identity, + /// The Metadata that is set. + metadata: Metadata, + /// The key used for the metadata. + key: String, +} + /// A persistent storage type to store the SRC-7; Metadata Standard type. /// /// # Additional Information @@ -166,6 +179,12 @@ pub fn _set_metadata( key: String, metadata: Metadata, ) { + log(SetMetadataEvent { + asset, + sender: msg_sender().unwrap(), + metadata, + key, + }); metadata_key.insert(asset, key, metadata); } diff --git a/libs/src/bytecode.sw b/libs/src/bytecode.sw index e8fa80c6..c691fcfc 100644 --- a/libs/src/bytecode.sw +++ b/libs/src/bytecode.sw @@ -16,6 +16,10 @@ use ::bytecode::utils::{_compute_bytecode_root, _predicate_address_from_root, _s /// /// * [b256] - The bytecode root of the contract or predicate. /// +/// # Reverts +/// +/// * When the bytecode is empty. +/// /// # Examples /// /// ```sway @@ -41,6 +45,10 @@ pub fn compute_bytecode_root(bytecode: Vec) -> b256 { /// /// * [b256] - The bytecode root of the contract or predicate. /// +/// # Reverts +/// +/// * When the bytecode is empty. +/// /// # Examples /// /// ```sway @@ -71,6 +79,11 @@ pub fn compute_bytecode_root_with_configurables( /// /// * [Address] - The address of the predicate. /// +/// +/// # Reverts +/// +/// * When the bytecode is empty. +/// /// # Examples /// /// ```sway @@ -97,6 +110,10 @@ pub fn compute_predicate_address(bytecode: Vec) -> Address { /// /// * [Address] - The address of the predicate. /// +/// # Reverts +/// +/// * When the bytecode is empty. +/// /// # Examples /// /// ```sway @@ -182,6 +199,7 @@ pub fn swap_configurables( /// /// # Reverts /// +/// * When the bytecode is empty. /// * When the contract's bytecode root does not match the passed bytecode. /// /// # Examples @@ -211,6 +229,7 @@ pub fn verify_contract_bytecode(contract_id: ContractId, bytecode: Vec) { /// /// # Reverts /// +/// * When the bytecode is empty. /// * When the contract's bytecode root does not match the passed bytecode. /// /// # Examples @@ -246,6 +265,7 @@ pub fn verify_contract_bytecode_with_configurables( /// /// # Reverts /// +/// * When the bytecode is empty. /// * When the predicate's address does not match the passed address. /// /// # Examples @@ -275,6 +295,7 @@ pub fn verify_predicate_address(predicate_id: Address, bytecode: Vec) { /// /// # Reverts /// +/// * When the bytecode is empty. /// * When the predicate's address does not match the passed address. /// /// # Examples diff --git a/libs/src/bytecode/utils.sw b/libs/src/bytecode/utils.sw index a8dec43a..ddb84191 100644 --- a/libs/src/bytecode/utils.sw +++ b/libs/src/bytecode/utils.sw @@ -89,6 +89,7 @@ fn _generate_leaves(bytecode: raw_slice) -> raw_slice { /// Takes some bytecode and computes the bytecode root. pub fn _compute_bytecode_root(bytecode: raw_slice) -> b256 { + assert(bytecode.number_of_bytes() != 0); let mut vec_digest = _generate_leaves(bytecode); let vec_digest_len = vec_digest.len::(); let mut size = (vec_digest_len + 1) >> 1; @@ -145,6 +146,9 @@ pub fn _swap_configurables( while configurable_iterator < configurables.len() { let (offset, data) = configurables.get(configurable_iterator).unwrap(); + // Make sure the configurable data doesnt overflow the bytecode + assert(offset + data.len() <= bytecode.len::()); + // Overwrite the configurable data into the bytecode data .ptr() diff --git a/libs/src/fixed_point.sw b/libs/src/fixed_point.sw deleted file mode 100644 index 0410cfe0..00000000 --- a/libs/src/fixed_point.sw +++ /dev/null @@ -1,8 +0,0 @@ -library; - -pub mod ufp32; -pub mod ufp64; -pub mod ufp128; -pub mod ifp64; -pub mod ifp128; -pub mod ifp256; diff --git a/libs/src/fixed_point/ifp128.sw b/libs/src/fixed_point/ifp128.sw deleted file mode 100644 index b9457c1d..00000000 --- a/libs/src/fixed_point/ifp128.sw +++ /dev/null @@ -1,570 +0,0 @@ -library; -// A wrapper library around the type for mathematical functions operating with signed 128-bit fixed point numbers. -use std::math::{Exponent, Power, Root}; -use ::fixed_point::ufp64::UFP64; - -/// The 128-bit signed fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `UFP64` number and a boolean. -pub struct IFP128 { - /// The underlying value representing the `IFP128` type. - underlying: UFP64, - /// The underlying boolean representing a negative value for the `IFP128` type. - non_negative: bool, -} - -impl From for IFP128 { - /// Creates IFP128 from UFP64. Note that IFP128::from(1) is 1 / 2^32 and not 1. - fn from(value: UFP64) -> Self { - Self { - underlying: value, - non_negative: true, - } - } -} - -impl IFP128 { - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `IFP128` type. - /// - /// # Examples - /// - /// ``sway - /// use sway_libs::fixed_point::ifp128::IFP128; - /// - /// fn foo() { - /// let bits = IFP128::bits(); - /// assert(bits == 72); - /// } - /// ``` - pub fn bits() -> u64 { - 72 - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` struct. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::max(); - /// assert(ifp128.underlying() == UFP64::max()); - /// } - /// ``` - pub fn max() -> Self { - Self::from(UFP64::max()) - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::min(); - /// assert(ifp128.underlying() == UFP64::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: UFP64::min(), - non_negative: false, - } - } - - /// The zero value of this type. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::zero(); - /// assert(ifp128.underlying() == UFP64::zero()); - /// } - /// ``` - pub fn zero() -> Self { - Self::from(UFP64::zero()) - } - - /// Inverts the sign for this type. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp128::IFP128; - /// - /// fn foo() { - /// let ifp128 = IFP128::zero(); - /// assert(ifp128.non_negative()); - /// let reverse = ifp128.sign_inverse(); - /// assert(!reverse.non_negative()); - /// } - /// ``` - pub fn sign_reverse(self) -> Self { - Self { - underlying: self.underlying, - non_negative: !self.non_negative, - } - } - - /// Returns whether a `IFP128` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `IFP128` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp128::IFP128; - /// - /// fn foo() { - /// let ifp128 = IFP128::zero(); - /// assert(ifp128.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == UFP64::zero() - } - - /// Returns the underlying `UFP64` representing the `IFP128`. - /// - /// # Returns - /// - /// * [UFP64] - The `UFP64` representing the `IFP128`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::zero(); - /// assert(ifp128.underlying() == UFP64::zero()); - /// } - /// ``` - pub fn underlying(self) -> UFP64 { - self.underlying - } - - /// Returns the underlying bool representing the postive or negative state of the IFP128. - /// - /// # Returns - /// - /// * [bool] - The `bool` representing whether the `IFP128` is non-negative or not. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp128::IFP128; - /// - /// fn foo() { - /// let ifp128 = IFP128::zero(); - /// assert(ifp128.non_negative() == false); - /// } - /// ``` - pub fn non_negative(self) -> bool { - self.non_negative - } -} - -impl core::ops::Eq for IFP128 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - && (self.underlying == Self::zero() - .underlying - || self.non_negative == other.non_negative) - } -} - -impl core::ops::Ord for IFP128 { - fn gt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - true - } else if !self.non_negative && self.non_negative { - false - } else if self.non_negative && self.non_negative { - self.underlying > other.underlying - } else { - self.underlying < other.underlying - } - } - - fn lt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - false - } else if !self.non_negative && self.non_negative { - true - } else if self.non_negative && self.non_negative { - self.underlying < other.underlying - } else { - self.underlying > other.underlying - } - } -} - -impl core::ops::Add for IFP128 { - /// Add a IFP128 to a IFP128. Panics on overflow. - fn add(self, other: Self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - if self.non_negative && !other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = false; - } - } else if !self.non_negative && other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = true; - } - } else { - // same sign - underlying = self.underlying + other.underlying; - } - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Subtract for IFP128 { - /// Subtract a IFP128 from a IFP128. Panics of overflow. - fn subtract(self, other: Self) -> Self { - self + other.sign_reverse() - } -} - -impl core::ops::Multiply for IFP128 { - /// Multiply a IFP128 with a IFP128. Panics of overflow. - fn multiply(self, other: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying * other.underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Divide for IFP128 { - /// Divide a IFP128 by a IFP128. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying / divisor.underlying, - non_negative: non_negative, - } - } -} - -impl IFP128 { - /// Creates IFP128 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u64] - The unsigned number to become the underlying value for the `IFP128`. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(1); - /// assert(ifp128.underlying() == UFP64::from_uint(1)); - /// } - /// ``` - pub fn from_uint(uint: u64) -> Self { - Self::from(UFP64::from_uint(uint)) - } -} - -impl IFP128 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [IFP128] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let recip = IFP128::recip(ifp128); - /// assert(recip.underlying() == UFP64::recip(UFP64::from(128))); - /// } - /// ``` - pub fn recip(number: IFP128) -> Self { - Self { - underlying: UFP64::recip(number.underlying), - non_negative: number.non_negative, - } - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let trunc = ifp128.trunc(); - /// assert(trunc.underlying() == UFP64::from(128).trunc()); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self { - underlying: self.underlying.trunc(), - non_negative: self.non_negative, - } - } -} - -impl IFP128 { - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let floor = ifp128.floor(); - /// assert(floor.underlying == UFP64::from(128).floor()); - /// } - /// ``` - pub fn floor(self) -> Self { - if self.non_negative { - self.trunc() - } else { - let trunc = self.underlying.trunc(); - if trunc != UFP64::zero() { - self.trunc() - Self::from(UFP64::from(1)) - } else { - self.trunc() - } - } - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [IFP128] - the newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let fract = ifp128.fract(); - /// assert(fract.underlying() == UFP64::from(128).fract()); - /// } - /// ``` - pub fn fract(self) -> Self { - Self { - underlying: self.underlying.fract(), - non_negative: self.non_negative, - } - } -} - -impl IFP128 { - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IF128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let ceil = ifp128.ceil(); - /// assert(ceil.underlying = UFP64::from(128).ceil()); - /// } - /// ``` - pub fn ceil(self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - - if self.non_negative { - underlying = self.underlying.ceil(); - } else { - let ceil = self.underlying.ceil(); - if ceil != self.underlying { - underlying = ceil + UFP64::from(1); - if ceil == UFP64::from(1) { - non_negative = true; - } - } else { - underlying = ceil; - } - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl IFP128 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [IFP128] - The newly created `IFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - /// - /// fn foo() { - /// let ifp128 = IFP128::from_uint(128); - /// let round = ifp128.round(); - /// assert(round.underlying() == UFP64::from(128).round()); - /// } - /// ``` - pub fn round(self) -> Self { - let mut underlying = self.underlying; - - if self.non_negative { - underlying = self.underlying.round(); - } else { - let floor = self.underlying.floor(); - let ceil = self.underlying.ceil(); - let diff_self_floor = self.underlying - floor; - let diff_ceil_self = ceil - self.underlying; - underlying = if diff_self_floor > diff_ceil_self { - floor - } else { - ceil - }; - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl Exponent for IFP128 { - /// Exponent function. e ^ x - fn exp(exponent: Self) -> Self { - let one = IFP128::from_uint(1); - - // Coefficients in the Taylor series up to the seventh power - let p2 = IFP128::from(UFP64::from(2147483648)); // p2 == 1 / 2! - let p3 = IFP128::from(UFP64::from(715827882)); // p3 == 1 / 3! - let p4 = IFP128::from(UFP64::from(178956970)); // p4 == 1 / 4! - let p5 = IFP128::from(UFP64::from(35791394)); // p5 == 1 / 5! - let p6 = IFP128::from(UFP64::from(5965232)); // p6 == 1 / 6! - let p7 = IFP128::from(UFP64::from(852176)); // p7 == 1 / 7! - // Common technique to counter losing significant numbers in usual approximation - // Taylor series approximation of exponentiation function minus 1. The subtraction is done to deal with accuracy issues - let res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = res_minus_1 + one; - res - } -} - -impl Power for IFP128 { - /// Power function. x ^ exponent - fn pow(self, exponent: u32) -> Self { - let ufp64_exponent = UFP64::from(exponent.as_u64()); - let non_negative = if !self.non_negative { - // roots of negative numbers are complex numbers which we lack for now - assert(ufp64_exponent.floor() == ufp64_exponent); - - let div_2 = ufp64_exponent / UFP64::from(2); - div_2.floor() == div_2 - } else { - true - }; - let mut underlying = self.underlying.pow(exponent); - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} diff --git a/libs/src/fixed_point/ifp256.sw b/libs/src/fixed_point/ifp256.sw deleted file mode 100644 index 9b7acf8f..00000000 --- a/libs/src/fixed_point/ifp256.sw +++ /dev/null @@ -1,570 +0,0 @@ -library; -// A wrapper library around the type for mathematical functions operating with signed 256-bit fixed point numbers. -use std::math::{Exponent, Power, Root}; -use ::fixed_point::ufp128::UFP128; - -/// The 256-bit signed fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `UFP128` number and a boolean. -pub struct IFP256 { - /// The underlying value representing the `IFP256` type. - underlying: UFP128, - /// The underlying boolean representing a negative value for the `IFP256` type. - non_negative: bool, -} - -impl From for IFP256 { - /// Creates IFP256 from UFP128. Note that IFP256::from(1) is 1 / 2^128 and not 1. - fn from(value: UFP128) -> Self { - Self { - underlying: value, - non_negative: true, - } - } -} - -impl IFP256 { - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `IFP256` type. - /// - /// # Examples - /// - /// ``sway - /// use sway_libs::fixed_point::ifp256::IFP256; - /// - /// fn foo() { - /// let bits = IFP256::bits(); - /// assert(bits == 136); - /// } - /// ``` - pub fn bits() -> u64 { - 136 - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` struct. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::max(); - /// assert(ifp256.underlying() == UFP128::max()); - /// } - /// ``` - pub fn max() -> Self { - Self::from(UFP128::max()) - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::min(); - /// assert(ifp256.underlying() == UFP128::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: UFP128::min(), - non_negative: false, - } - } - - /// The zero value of this type. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::zero(); - /// assert(ifp256.underlying() == UFP128::zero()); - /// } - /// ``` - pub fn zero() -> Self { - Self::from(UFP128::zero()) - } - - /// Inverts the sign for this type. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp256::IFP256; - /// - /// fn foo() { - /// let ifp256 = IFP256::zero(); - /// assert(ifp256.non_negative()); - /// let reverse = ifp256.sign_inverse(); - /// assert(!reverse.non_negative()); - /// } - /// ``` - pub fn sign_reverse(self) -> Self { - Self { - underlying: self.underlying, - non_negative: !self.non_negative, - } - } - - /// Returns whether a `IFP256` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `IFP256` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp256::IFP256; - /// - /// fn foo() { - /// let ifp256 = IFP256::zero(); - /// assert(ifp256.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == UFP128::zero() - } - - /// Returns the underlying `UFP128` representing the `IFP256`. - /// - /// # Returns - /// - /// * [UFP128] - The `UFP128` representing the `IFP256`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128}; - /// - /// fn foo() { - /// let ifp256 = IFP256::zero(); - /// assert(ifp256.underlying() == UFP128::zero()); - /// } - /// ``` - pub fn underlying(self) -> UFP128 { - self.underlying - } - - /// Returns the underlying bool representing the postive or negative state of the IFP256. - /// - /// # Returns - /// - /// * [bool] - The `bool` representing whether the `IFP256` is non-negative or not. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp256::IFP256; - /// - /// fn foo() { - /// let ifp256 = IFP256::zero(); - /// assert(ifp256.non_negative() == false); - /// } - /// ``` - pub fn non_negative(self) -> bool { - self.non_negative - } -} - -impl core::ops::Eq for IFP256 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - && (self.underlying == Self::zero() - .underlying - || self.non_negative == other.non_negative) - } -} - -impl core::ops::Ord for IFP256 { - fn gt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - true - } else if !self.non_negative && self.non_negative { - false - } else if self.non_negative && self.non_negative { - self.underlying > other.underlying - } else { - self.underlying < other.underlying - } - } - - fn lt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - false - } else if !self.non_negative && self.non_negative { - true - } else if self.non_negative && self.non_negative { - self.underlying < other.underlying - } else { - self.underlying > other.underlying - } - } -} - -impl core::ops::Add for IFP256 { - /// Add a IFP256 to a IFP256. Panics on overflow. - fn add(self, other: Self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - if self.non_negative && !other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = false; - } - } else if !self.non_negative && other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = true; - } - } else { - // same sign - underlying = self.underlying + other.underlying; - } - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Subtract for IFP256 { - /// Subtract a IFP256 from a IFP256. Panics of overflow. - fn subtract(self, other: Self) -> Self { - self + other.sign_reverse() - } -} - -impl core::ops::Multiply for IFP256 { - /// Multiply a IFP256 with a IFP256. Panics of overflow. - fn multiply(self, other: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying * other.underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Divide for IFP256 { - /// Divide a IFP256 by a IFP256. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying / divisor.underlying, - non_negative: non_negative, - } - } -} - -impl IFP256 { - /// Creates IFP256 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u64] - The unsigned number to become the underlying value for the `IFP256`. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(1); - /// assert(ifp256.underlying() == UFP128::from_uint(1)); - /// } - /// ``` - pub fn from_uint(uint: u64) -> Self { - Self::from(UFP128::from_uint(uint)) - } -} - -impl IFP256 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [IFP126] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let recip = IFP256::recip(ifp256); - /// assert(recip.underlying() == UFP128::recip(UFP128::from(128))); - /// } - /// ``` - pub fn recip(number: IFP256) -> Self { - Self { - underlying: UFP128::recip(number.underlying), - non_negative: number.non_negative, - } - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let trunc = ifp256.trunc(); - /// assert(trunc.underlying() == UFP128::from(128).trunc()); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self { - underlying: self.underlying.trunc(), - non_negative: self.non_negative, - } - } -} - -impl IFP256 { - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let floor = ifp256.floor(); - /// assert(floor.underlying() == UFP128::from(128).floor()); - /// } - /// ``` - pub fn floor(self) -> Self { - if self.non_negative { - self.trunc() - } else { - let trunc = self.underlying.trunc(); - if trunc != UFP128::zero() { - self.trunc() - Self::from(UFP128::from((1, 0))) - } else { - self.trunc() - } - } - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [IFP256] - the newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let fract = ifp256.fract(); - /// assert(fract.underlying() == UFP128::from(128).fract()); - /// } - /// ``` - pub fn fract(self) -> Self { - Self { - underlying: self.underlying.fract(), - non_negative: self.non_negative, - } - } -} - -impl IFP256 { - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let ceil = ifp256.ceil(); - /// assert(ceil.underlying() = UFP128::from(128).ceil().underlying()); - /// } - /// ``` - pub fn ceil(self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - - if self.non_negative { - underlying = self.underlying.ceil(); - } else { - let ceil = self.underlying.ceil(); - if ceil != self.underlying { - underlying = ceil + UFP128::from((1, 0)); - if ceil == UFP128::from((1, 0)) { - non_negative = true; - } - } else { - underlying = ceil; - } - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl IFP256 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [IFP256] - The newly created `IFP256` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128} - /// - /// fn foo() { - /// let ifp256 = IFP256::from_uint(128); - /// let round = ifp256.round(); - /// assert(round.underlying() == UFP128::from(128).round().underlying()); - /// } - /// ``` - pub fn round(self) -> Self { - let mut underlying = self.underlying; - - if self.non_negative { - underlying = self.underlying.round(); - } else { - let floor = self.underlying.floor(); - let ceil = self.underlying.ceil(); - let diff_self_floor = self.underlying - floor; - let diff_ceil_self = ceil - self.underlying; - underlying = if diff_self_floor > diff_ceil_self { - floor - } else { - ceil - }; - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl Exponent for IFP256 { - /// Exponent function. e ^ x - fn exp(exponent: Self) -> Self { - let one = IFP256::from_uint(1); - - // Coefficients in the Taylor series up to the seventh power - let p2 = IFP256::from(UFP128::from((0, 2147483648))); // p2 == 1 / 2! - let p3 = IFP256::from(UFP128::from((0, 715827882))); // p3 == 1 / 3! - let p4 = IFP256::from(UFP128::from((0, 178956970))); // p4 == 1 / 4! - let p5 = IFP256::from(UFP128::from((0, 35791394))); // p5 == 1 / 5! - let p6 = IFP256::from(UFP128::from((0, 5965232))); // p6 == 1 / 6! - let p7 = IFP256::from(UFP128::from((0, 852176))); // p7 == 1 / 7! - // Common technique to counter losing significant numbers in usual approximation - // Taylor series approximation of exponentiation function minus 1. The subtraction is done to deal with accuracy issues - let res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = res_minus_1 + one; - res - } -} - -impl Power for IFP256 { - /// Power function. x ^ exponent - fn pow(self, exponent: u32) -> Self { - let ufp128_exponent = UFP128::from((0, exponent.as_u64())); - let non_negative = if !self.non_negative { - // roots of negative numbers are complex numbers which we lack for now - assert(ufp128_exponent.floor() == ufp128_exponent); - - let div_2 = ufp128_exponent / UFP128::from((2, 0)); - div_2.floor() == div_2 - } else { - true - }; - let mut underlying = self.underlying.pow(exponent); - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} diff --git a/libs/src/fixed_point/ifp64.sw b/libs/src/fixed_point/ifp64.sw deleted file mode 100644 index 680536d6..00000000 --- a/libs/src/fixed_point/ifp64.sw +++ /dev/null @@ -1,570 +0,0 @@ -library; -// A wrapper library around the u32 type for mathematical functions operating with signed 64-bit fixed point numbers. -use std::math::*; -use ::fixed_point::ufp32::UFP32; - -/// The 64-bit signed fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `UFP32` number and a boolean. -pub struct IFP64 { - /// The underlying value representing the `IFP64` type. - underlying: UFP32, - /// The underlying boolean representing a negative value for the `IFP64` type. - non_negative: bool, -} - -impl From for IFP64 { - /// Creates IFP64 from UFP32. Note that IFP64::from(1) is 1 / 2^32 and not 1. - fn from(value: UFP32) -> Self { - Self { - underlying: value, - non_negative: true, - } - } -} - -impl IFP64 { - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `IFP64` type. - /// - /// # Examples - /// - /// ``sway - /// use sway_libs::fixed_point::ifp64::IFP64; - /// - /// fn foo() { - /// let bits = IFP64::bits(); - /// assert(bits == 64); - /// } - /// ``` - pub fn bits() -> u64 { - 64 - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` struct. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::max(); - /// assert(ifp64.underlying() == UFP32::max()); - /// } - /// ``` - pub fn max() -> Self { - Self::from(UFP32::max()) - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::min(); - /// assert(ifp64.underlying() == UFP32::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: UFP32::min(), - non_negative: false, - } - } - - /// The zero value of this type. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::zero(); - /// assert(ifp64.underlying() == UFP32::zero()); - /// } - /// ``` - pub fn zero() -> Self { - Self::from(UFP32::zero()) - } - - /// Returns whether a `IFP64` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `IFP64` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp64::IFP64; - /// - /// fn foo() { - /// let ifp64 = IFP64::zero(); - /// assert(ifp64.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == UFP32::zero() - } - - /// Inverts the sign for this type. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp64::IFP64; - /// - /// fn foo() { - /// let ifp64 = IFP64::zero(); - /// assert(ifp64.non_negative()); - /// let reverse = ifp64.sign_inverse(); - /// assert(!reverse.non_negative()); - /// } - /// ``` - fn sign_reverse(self) -> Self { - Self { - underlying: self.underlying, - non_negative: !self.non_negative, - } - } - - /// Returns the underlying `UFP32` representing the `IFP64`. - /// - /// # Returns - /// - /// * [UFP32] - The `UFP32` representing the `IFP64`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::zero(); - /// assert(ifp64.underlying() == UFP32::zero()); - /// } - /// ``` - pub fn underlying(self) -> UFP32 { - self.underlying - } - - /// Returns the underlying bool representing the postive or negative state of the IFP64. - /// - /// # Returns - /// - /// * [bool] - The `bool` representing whether the `IFP64` is non-negative or not. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ifp64::IFP64; - /// - /// fn foo() { - /// let ifp64 = IFP64::zero(); - /// assert(ifp64.non_negative() == false); - /// } - /// ``` - pub fn non_negative(self) -> bool { - self.non_negative - } -} - -impl core::ops::Eq for IFP64 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - && (self.underlying == Self::zero() - .underlying - || self.non_negative == other.non_negative) - } -} - -impl core::ops::Ord for IFP64 { - fn gt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - true - } else if !self.non_negative && self.non_negative { - false - } else if self.non_negative && self.non_negative { - self.underlying > other.underlying - } else { - self.underlying < other.underlying - } - } - - fn lt(self, other: Self) -> bool { - if self.non_negative && !self.non_negative { - false - } else if !self.non_negative && self.non_negative { - true - } else if self.non_negative && self.non_negative { - self.underlying < other.underlying - } else { - self.underlying > other.underlying - } - } -} - -impl core::ops::Add for IFP64 { - /// Add a IFP64 to a IFP64. Panics on overflow. - fn add(self, other: Self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - if self.non_negative && !other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = false; - } - } else if !self.non_negative && other.non_negative { - if self.underlying > other.underlying { - underlying = self.underlying - other.underlying; - } else { - underlying = other.underlying - self.underlying; - non_negative = true; - } - } else { - // same sign - underlying = self.underlying + other.underlying; - } - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Subtract for IFP64 { - /// Subtract a IFP64 from a IFP64. Panics of overflow. - fn subtract(self, other: Self) -> Self { - self + other.sign_reverse() - } -} - -impl core::ops::Multiply for IFP64 { - /// Multiply a IFP64 with a IFP64. Panics of overflow. - fn multiply(self, other: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying * other.underlying, - non_negative: non_negative, - } - } -} - -impl core::ops::Divide for IFP64 { - /// Divide a IFP64 by a IFP64. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let non_negative = if (self.non_negative - && !self.non_negative) - || (!self.non_negative - && self.non_negative) - { - false - } else { - true - }; - Self { - underlying: self.underlying / divisor.underlying, - non_negative: non_negative, - } - } -} - -impl IFP64 { - /// Creates IFP64 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u32] - The unsigned number to become the underlying value for the `IFP64`. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(1u32); - /// assert(ifp64.underlying() == UFP32::from_uint(1u32)); - /// } - /// ``` - pub fn from_uint(uint: u32) -> Self { - Self::from(UFP32::from_uint(uint)) - } -} - -impl IFP64 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [IFP64] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128u32); - /// let recip = IFP64::recip(ifp64); - /// assert(recip.underlying() == UFP32::recip(UFP32::from(128u32))); - /// } - /// ``` - pub fn recip(number: IFP64) -> Self { - Self { - underlying: UFP32::recip(number.underlying), - non_negative: number.non_negative, - } - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64:IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128u32); - /// let trunc = ifp64.trunc(); - /// assert(trunc.underlying() == UFP32::from(128u32).trunc()); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self { - underlying: self.underlying.trunc(), - non_negative: self.non_negative, - } - } -} - -impl IFP64 { - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128u32); - /// let floor = ifp64.floor(); - /// assert(floor.underlying() == UFP32::from(128u32).trunc().underlying()); - /// } - /// ``` - pub fn floor(self) -> Self { - if self.non_negative { - self.trunc() - } else { - let trunc = self.underlying.trunc(); - if trunc != UFP32::zero() { - self.trunc() - Self::from(UFP32::from(1u32)) - } else { - self.trunc() - } - } - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [IFP64] - the newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128u32); - /// let fract = ifp64.fract(); - /// assert(fract.underlying() == UFP32::from(128u32).fract()); - /// } - /// ``` - pub fn fract(self) -> Self { - Self { - underlying: self.underlying.fract(), - non_negative: self.non_negative, - } - } -} - -impl IFP64 { - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128u32); - /// let ceil = ifp64.ceil(); - /// assert(ceil.underlying() = UFP32::from(128u32).ceil()); - /// } - /// ``` - pub fn ceil(self) -> Self { - let mut underlying = self.underlying; - let mut non_negative = self.non_negative; - - if self.non_negative { - underlying = self.underlying.ceil(); - } else { - let ceil = self.underlying.ceil(); - if ceil != self.underlying { - underlying = ceil + UFP32::from(1u32); - if ceil == UFP32::from(1u32) { - non_negative = true; - } - } else { - underlying = ceil; - } - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl IFP64 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [IFP64] - The newly created `IFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; - /// - /// fn foo() { - /// let ifp64 = IFP64::from_uint(128_u32); - /// let round = ifp64.round(); - /// assert(round.underlying() == UFP32::from(128u32).round()); - /// } - /// ``` - pub fn round(self) -> Self { - let mut underlying = self.underlying; - - if self.non_negative { - underlying = self.underlying.round(); - } else { - let floor = self.underlying.floor(); - let ceil = self.underlying.ceil(); - let diff_self_floor = self.underlying - floor; - let diff_ceil_self = ceil - self.underlying; - underlying = if diff_self_floor > diff_ceil_self { - floor - } else { - ceil - }; - } - Self { - underlying: underlying, - non_negative: self.non_negative, - } - } -} - -impl Exponent for IFP64 { - /// Exponent function. e ^ x - fn exp(exponent: Self) -> Self { - let one = IFP64::from_uint(1u32); - - // Coefficients in the Taylor series up to the seventh power - let p2 = IFP64::from(UFP32::from(32768u32)); // p2 == 1 / 2! - let p3 = IFP64::from(UFP32::from(10922u32)); // p3 == 1 / 3! - let p4 = IFP64::from(UFP32::from(2730u32)); // p4 == 1 / 4! - let p5 = IFP64::from(UFP32::from(546u32)); // p5 == 1 / 5! - let p6 = IFP64::from(UFP32::from(91u32)); // p6 == 1 / 6! - let p7 = IFP64::from(UFP32::from(13u32)); // p7 == 1 / 7! - // Common technique to counter losing significant numbers in usual approximation - // Taylor series approximation of exponentiation function minus 1. The subtraction is done to deal with accuracy issues - let res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = res_minus_1 + one; - res - } -} - -impl Power for IFP64 { - /// Power function. x ^ exponent - fn pow(self, exponent: u32) -> Self { - let ufp32_exponent = UFP32::from(exponent); - let non_negative = if !self.non_negative { - // roots of negative numbers are complex numbers which we lack for now - assert(ufp32_exponent.floor() == ufp32_exponent); - - let div_2 = ufp32_exponent / UFP32::from(2u32); - div_2.floor() == div_2 - } else { - true - }; - let mut underlying = self.underlying.pow(exponent); - Self { - underlying: underlying, - non_negative: non_negative, - } - } -} diff --git a/libs/src/fixed_point/ufp128.sw b/libs/src/fixed_point/ufp128.sw deleted file mode 100644 index 09e60f40..00000000 --- a/libs/src/fixed_point/ufp128.sw +++ /dev/null @@ -1,483 +0,0 @@ -library; -// A wrapper around U128 type for a library for Sway for mathematical functions operating with unsigned 64.64-bit fixed point numbers. -use std::{math::{Exponent, Power, Root}, u128::U128}; - -/// The 128-bit unsigned fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `U128` number. -pub struct UFP128 { - /// The underlying value representing the `UFP128` type. - underlying: U128, -} - -impl From<(u64, u64)> for UFP128 { - fn from(int_fract_tuple: (u64, u64)) -> Self { - Self { - underlying: U128::from(int_fract_tuple), - } - } -} - -impl From for UFP128 { - fn from(u128: U128) -> Self { - Self { - underlying: u128, - } - } -} - -impl UFP128 { - /// The zero value of this type. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::zero(); - /// assert(ufp128.underlying() == U128::from((0, 0))); - /// } - /// ``` - pub fn zero() -> Self { - Self { - underlying: U128::from((0, 0)), - } - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// use std::u128::U128; - /// - /// fn foo() { - /// let ufp128 = UFP128::min(); - /// assert(ufp128.underlying() == U128::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: U128::min(), - } - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` struct. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// use std::u128::U128; - /// - /// fn foo() { - /// let ufp128 = UFP128::max(); - /// assert(ufp128.underlying() == U128::max()); - /// } - /// ``` - pub fn max() -> Self { - Self { - underlying: U128::max(), - } - } - - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `UFP128` type. - /// - /// # Examples - /// - /// ``sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let bits = UFP128::bits(); - /// assert(bits == 128); - /// } - /// ``` - pub fn bits() -> u64 { - 128 - } - - /// Returns whether a `UFP128` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `UFP128` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::zero(); - /// assert(ufp128.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == U128::zero() - } - - /// Returns the underlying `U128` representing the `UFP128`. - /// - /// # Returns - /// - /// * [U128] - The `U128` representing the `UFP128`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp128 = UFP128::zero(); - /// assert(ufp128.underlying() == U128::zero()); - /// } - /// ``` - pub fn underlying(self) -> U128 { - self.underlying - } -} - -impl UFP128 { - /// Creates UFP128 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u64] - The unsigned number to become the underlying value for the `UFP128`. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// use std::u128::U128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(1); - /// assert(ufp128.underlying() == U128::from((1, 0)); - /// } - /// ``` - pub fn from_uint(uint: u64) -> Self { - Self { - underlying: U128::from((uint, 0)), - } - } -} - -impl core::ops::Eq for UFP128 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - } -} - -impl core::ops::Ord for UFP128 { - fn gt(self, other: Self) -> bool { - self.underlying > other.underlying - } - - fn lt(self, other: Self) -> bool { - self.underlying < other.underlying - } -} - -impl core::ops::Add for UFP128 { - /// Add a UFP128 to a UFP128. Panics on overflow. - fn add(self, other: Self) -> Self { - UFP128 { - underlying: self.underlying + other.underlying, - } - } -} - -impl core::ops::Subtract for UFP128 { - /// Subtract a UFP128 from a UFP128. Panics of overflow. - fn subtract(self, other: Self) -> Self { - // If trying to subtract a larger number, panic. - assert(!(self.underlying < other.underlying)); - - UFP128 { - underlying: self.underlying - other.underlying, - } - } -} - -impl core::ops::Multiply for UFP128 { - /// Multiply a UFP128 with a UFP128. Panics on overflow. - fn multiply(self, other: Self) -> Self { - let self_u64 = (0, 0, self.underlying.upper(), self.underlying.lower()); - let other_u64 = (0, 0, other.underlying.upper(), other.underlying.lower()); - let self_u256 = asm(r1: self_u64) { - r1: u256 - }; - let other_u256 = asm(r1: other_u64) { - r1: u256 - }; - - let self_multiply_other = self_u256 * other_u256; - let res_u256 = self_multiply_other >> 64; - - let (a, b, c, d) = asm(r1: res_u256) { - r1: (u64, u64, u64, u64) - }; - if a != 0 || b != 0 { - // panic on overflow - revert(0); - } - Self::from((c, d)) - } -} - -impl core::ops::Divide for UFP128 { - /// Divide a UFP128 by a UFP128. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let zero = UFP128::zero(); - - assert(divisor != zero); - - // Conversion to u256 done to ensure no overflow happen - // and maximal precision is avaliable - // as it makes possible to multiply by the denominator in - // all cases - let self_u64 = (0, 0, self.underlying.upper(), self.underlying.lower()); - let divisor_u64 = (0, 0, divisor.underlying.upper(), divisor.underlying.lower()); - let self_u256 = asm(r1: self_u64) { - r1: u256 - }; - let divisor_u256 = asm(r1: divisor_u64) { - r1: u256 - }; - - // Multiply by denominator to ensure accuracy - let res_u256 = (self_u256 << 64) / divisor_u256; - let (a, b, c, d) = asm(r1: res_u256) { - r1: (u64, u64, u64, u64) - }; - - if a != 0 || b != 0 { - // panic on overflow - revert(0); - } - Self::from((c, d)) - } -} - -impl UFP128 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [UFP128] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp64 = UFP128::from_uint(128); - /// let recip = UFP64::recip(ufp64); - /// assert(recip.underlying() == U128::from((33554432, 0)); - /// } - /// ``` - pub fn recip(number: UFP128) -> Self { - let one = UFP128::from((1, 0)); - - one / number - } - - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(128); - /// let floor = ufp128.floor(); - /// assert(floor.underlying() == U128::from((0,0))); - /// } - /// ``` - pub fn floor(self) -> Self { - Self::from((self.underlying.upper(), 0)) - } - - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(128); - /// let ceil = ufp128.ceil(); - /// assert(ceil.underlying() = U128::from((4294967296, 0))); - /// } - /// ``` - pub fn ceil(self) -> Self { - let val = self.underlying; - if val.lower() == 0 { - return Self::from((val.upper(), 0)); - } else { - return Self::from((val.upper() + 1, 0)); - } - } -} - -impl UFP128 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(128); - /// let round = ufp128.round(); - /// assert(round.underlying() == U128::from(0,0))); - /// } - /// ``` - pub fn round(self) -> Self { - let floor = self.floor(); - let ceil = self.ceil(); - let diff_self_floor = self - floor; - let diff_ceil_self = ceil - self; - if diff_self_floor < diff_ceil_self { - return floor; - } else { - return ceil; - } - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [UFP128] - The newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(128); - /// let trunc = ufp128.trunc(); - /// assert(trunc.underlying() == U128::from((0,0))); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self::from((self.underlying.upper(), 0)) - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [UFP128] - the newly created `UFP128` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp128::UFP128; - /// - /// fn foo() { - /// let ufp128 = UFP128::from_uint(128); - /// let fract = ufp128.fract(); - /// assert(fract.underlying() == U128::from((0, 0))); - /// } - /// ``` - pub fn fract(self) -> Self { - Self::from((0, self.underlying.lower())) - } -} - -impl Root for UFP128 { - fn sqrt(self) -> Self { - let numerator_root = self.underlying.sqrt(); - let numerator = numerator_root * U128::from((0, 2 << 32)); - Self::from((numerator.upper(), numerator.lower())) - } -} - -impl Power for UFP128 { - fn pow(self, exponent: u32) -> Self { - let nominator_pow = self.underlying.pow(exponent); - let u128_2 = U128::from((0, 2)); - let two_pow_64_n_minus_1 = u128_2.pow((64u32 * (exponent - 1u32))); - let nominator = nominator_pow / two_pow_64_n_minus_1; - Self::from((nominator.upper(), nominator.lower())) - } -} - -// TODO: uncomment and change accordingly, when signed integers will be added -// impl Logarithm for UFP128 { -// fn log(self, base: Self) -> Self { -// let nominator_log = self.underlying.log(base); -// let res = (nominator_log - U128::from(0, 64 * 2.log(base))) * U128::from(1, 0); -// UFP128 { -// underlying: res -// } -// } -// } -impl Exponent for UFP128 { - fn exp(exponent: Self) -> Self { - let one = UFP128::from((1, 0)); - let p2 = one / UFP128::from((2, 0)); - let p3 = one / UFP128::from((6, 0)); - let p4 = one / UFP128::from((24, 0)); - let p5 = one / UFP128::from((120, 0)); - let p6 = one / UFP128::from((720, 0)); - let p7 = one / UFP128::from((5040, 0)); - - // common technique to counter losing sugnifucant numbers in usual approximation - let _res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = one; - res - } -} diff --git a/libs/src/fixed_point/ufp32.sw b/libs/src/fixed_point/ufp32.sw deleted file mode 100644 index 6394be92..00000000 --- a/libs/src/fixed_point/ufp32.sw +++ /dev/null @@ -1,507 +0,0 @@ -library; -// A wrapper library around the u32 type for mathematical functions operating with unsigned 32-bit fixed point numbers. -use std::math::*; - -/// The 32-bit unsigned fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `u32` number. -pub struct UFP32 { - /// The underlying value representing the `UFP32` type. - underlying: u32, -} - -impl From for UFP32 { - /// Creates UFP32 from u32. Note that UFP32::from(1) is 1 / 2^32 and not 1. - fn from(underlying: u32) -> Self { - Self { underlying } - } -} - -impl UFP32 { - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `UFP32` type. - /// - /// # Examples - /// - /// ``sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let bits = UFP32::bits(); - /// assert(bits == 32); - /// } - /// ``` - pub fn bits() -> u64 { - 32 - } - - /// Convenience function to know the denominator. - /// - /// # Returns - /// - /// * [u32] - The value of the denominator for the `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let denominator = UFP32::denominator(); - /// assert(denominator == 65536u32); - /// } - /// ``` - pub fn denominator() -> u32 { - 1u32 << 16 - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` struct. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::max(); - /// assert(ufp32.underlying() == u32::max()); - /// } - /// ``` - pub fn max() -> Self { - Self { - underlying: u32::max(), - } - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::min(); - /// assert(ufp32.underlying() == u32::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: u32::min(), - } - } - - /// The zero value of this type. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::zero(); - /// assert(ufp32.underlying() == 0u32); - /// } - /// ``` - pub fn zero() -> Self { - Self { - underlying: 0u32, - } - } - - /// Returns whether a `UFP32` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `UFP32` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::zero(); - /// assert(ufp32.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == 0u32 - } - - /// Returns the underlying `u32` representing the `UFP32`. - /// - /// # Returns - /// - /// * [u32] - The `u32` representing the `UFP32`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::zero(); - /// assert(ufp32.underlying() == 0u32); - /// } - /// ``` - pub fn underlying(self) -> u32 { - self.underlying - } -} - -impl core::ops::Eq for UFP32 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - } -} - -impl core::ops::Ord for UFP32 { - fn gt(self, other: Self) -> bool { - self.underlying > other.underlying - } - - fn lt(self, other: Self) -> bool { - self.underlying < other.underlying - } -} - -impl core::ops::Add for UFP32 { - /// Add a UFP32 to a UFP32. Panics on overflow. - fn add(self, other: Self) -> Self { - Self { - underlying: self.underlying + other.underlying, - } - } -} - -impl core::ops::Subtract for UFP32 { - /// Subtract a UFP32 from a UFP32. Panics of overflow. - fn subtract(self, other: Self) -> Self { - // If trying to subtract a larger number, panic. - assert(self.underlying >= other.underlying); - - Self { - underlying: self.underlying - other.underlying, - } - } -} - -impl core::ops::Multiply for UFP32 { - /// Multiply a UFP32 with a UFP32. Panics of overflow. - fn multiply(self, other: Self) -> Self { - let self_u64: u64 = self.underlying.as_u64(); - let other_u64: u64 = other.underlying.as_u64(); - - let self_multiply_other = self_u64 * other_u64; - let res_u64 = self_multiply_other >> 16; - if res_u64 > u32::max().as_u64() { - // panic on overflow - revert(0); - } - - Self { - underlying: asm(ptr: res_u64) { - ptr: u32 - }, - } - } -} - -impl core::ops::Divide for UFP32 { - /// Divide a UFP32 by a UFP32. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let zero = UFP32::zero(); - assert(divisor != zero); - - let denominator: u64 = Self::denominator().as_u64(); - // Conversion to U64 done to ensure no overflow happen - // and maximal precision is avaliable - // as it makes possible to multiply by the denominator in - // all cases - let self_u64: u64 = self.underlying.as_u64(); - let divisor_u64: u64 = divisor.underlying.as_u64(); - - // Multiply by denominator to ensure accuracy - let res_u64 = self_u64 * denominator / divisor_u64; - - if res_u64 > u32::max().as_u64() { - // panic on overflow - revert(0); - } - Self { - underlying: asm(ptr: res_u64) { - ptr: u32 - }, - } - } -} - -impl UFP32 { - /// Creates UFP32 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u32] - The unsigned number to become the underlying value for the `UFP32`. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(1u32); - /// assert(ufp32.underlying() == 65536u32); - /// } - /// ``` - pub fn from_uint(uint: u32) -> Self { - Self { - underlying: Self::denominator() * uint, - } - } -} - -impl UFP32 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [UFP32] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128u32); - /// let recip = UFP32::recip(ufp32); - /// assert(recip.underlying() == 512u32); - /// } - /// ``` - pub fn recip(number: UFP32) -> Self { - let one = UFP32::from_uint(1u32); - - let res = one / number; - res - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128u32); - /// let trunc = ufp32.trunc(); - /// assert(trunc.underlying() == 0); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self { - // first move to the right (divide by the denominator) - // to get rid of fractional part, than move to the - // left (multiply by the denominator), to ensure - // fixed-point structure - underlying: (self.underlying >> 16) << 16, - } - } -} - -impl UFP32 { - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128u32); - /// let floor = ufp32.floor(); - /// assert(floor.underlying() == 0); - /// } - /// ``` - pub fn floor(self) -> Self { - return self.trunc(); - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [UFP32] - the newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128u32); - /// let fract = ufp32.fract(); - /// assert(fract.underlying() == 0); - /// } - /// ``` - pub fn fract(self) -> Self { - Self { - // first move to the left (multiply by the denominator) - // to get rid of integer part, than move to the - // right (divide by the denominator), to ensure - // fixed-point structure - underlying: ((self.underlying << 16) - u32::max() - 1u32) >> 16, - } - } -} - -impl UFP32 { - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128u32); - /// let ceil = ufp32.ceil(); - /// assert(ceil.underlying() = 65536u32); - /// } - /// ``` - pub fn ceil(self) -> Self { - if self.fract().underlying != 0u32 { - let res = self.trunc() + UFP32::from_uint(1u32); - return res; - } - return self; - } -} - -impl UFP32 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [UFP32] - The newly created `UFP32` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp32::UFP32; - /// - /// fn foo() { - /// let ufp32 = UFP32::from_uint(128_u32); - /// let round = ufp32.round(); - /// assert(round.underlying() == 0); - /// } - /// ``` - pub fn round(self) -> Self { - let floor = self.floor(); - let ceil = self.ceil(); - let diff_self_floor = self - floor; - let diff_ceil_self = ceil - self; - - // Check if we are closer to the floor or to the ceiling - if diff_self_floor < diff_ceil_self { - return floor; - } else { - return ceil; - } - } -} - -impl Root for UFP32 { - /// Sqaure root for UFP32 - fn sqrt(self) -> Self { - let nominator_root = self.underlying.sqrt(); - // Need to multiply over 2 ^ 16, as the square root of the denominator - // is also taken and we need to ensure that the denominator is constant - let nominator = nominator_root << 16; - Self { - underlying: nominator, - } - } -} - -impl Exponent for UFP32 { - /// Exponent function. e ^ x - fn exp(exponent: Self) -> Self { - let one = UFP32::from_uint(1u32); - - // Coefficients in the Taylor series up to the seventh power - let p2 = UFP32::from(2147483648u32); // p2 == 1 / 2! - let p3 = UFP32::from(715827882u32); // p3 == 1 / 3! - let p4 = UFP32::from(178956970u32); // p4 == 1 / 4! - let p5 = UFP32::from(35791394u32); // p5 == 1 / 5! - let p6 = UFP32::from(5965232u32); // p6 == 1 / 6! - let p7 = UFP32::from(852176u32); // p7 == 1 / 7! - // Common technique to counter losing significant numbers in usual approximation - // Taylor series approximation of exponentiation function minus 1. The subtraction is done to deal with accuracy issues - let res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = res_minus_1 + one; - res - } -} - -impl Power for UFP32 { - /// Power function. x ^ exponent - fn pow(self, exponent: u32) -> Self { - let nominator_pow = self.underlying.pow(exponent); - // As we need to ensure the fixed point structure - // which means that the denominator is always 2 ^ 16 - // we need to divide the nominator by 2 ^ (16 * exponent - 1) - // - 1 is the formula is due to denominator need to stay 2 ^ 16 - let nominator = nominator_pow >> 16 * (exponent - 1u32).as_u64(); - - if nominator > u32::max() { - // panic on overflow - revert(0); - } - Self { - underlying: nominator, - } - } -} diff --git a/libs/src/fixed_point/ufp64.sw b/libs/src/fixed_point/ufp64.sw deleted file mode 100644 index 825cd1a5..00000000 --- a/libs/src/fixed_point/ufp64.sw +++ /dev/null @@ -1,502 +0,0 @@ -library; -// A wrapper library around the u64 type for mathematical functions operating with unsigned 64-bit fixed point numbers. -use std::{math::{Exponent, Power, Root}, u128::U128}; - -/// The 64-bit unsigned fixed point number type. -/// -/// # Additional Information -/// -/// Represented by an underlying `u64` number. -pub struct UFP64 { - /// The underlying value representing the `UFP64` type. - underlying: u64, -} - -impl From for UFP64 { - /// Creates UFP64 from u64. Note that UFP64::from(1) is 1 / 2^32 and not 1. - fn from(underlying: u64) -> Self { - Self { underlying } - } -} - -impl UFP64 { - /// The size of this type in bits. - /// - /// # Returns - /// - /// [u64] - The defined size of the `UFP64` type. - /// - /// # Examples - /// - /// ``sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let bits = UFP64::bits(); - /// assert(bits == 64); - /// } - /// ``` - pub fn bits() -> u64 { - 64 - } - - /// Convenience function to know the denominator. - /// - /// # Returns - /// - /// * [u64] - The value of the denominator for the `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let denominator = UFP64::denominator(); - /// assert(denominator == 4294967296); - /// } - /// ``` - pub fn denominator() -> u64 { - 1 << 32 - } - - /// The largest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` struct. - /// - /// # Examples - /// - /// ```sway - /// use v::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::max(); - /// assert(ufp64.underlying() == u64::max()); - /// } - /// ``` - pub fn max() -> Self { - Self { - underlying: u64::max(), - } - } - - /// The smallest value that can be represented by this type. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::min(); - /// assert(ufp64.underlying() == u64::min()); - /// } - /// ``` - pub fn min() -> Self { - Self { - underlying: u64::min(), - } - } - - /// The zero value of this type. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::zero(); - /// assert(ufp64.underlying() == 0); - /// } - /// ``` - pub fn zero() -> Self { - Self { underlying: 0 } - } - - /// Returns whether a `UFP64` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `UFP64` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::zero(); - /// assert(ufp64.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self.underlying == 0 - } - - /// Returns the underlying `u64` representing the `UFP64`. - /// - /// # Returns - /// - /// * [u64] - The `u64` representing the `UFP64`. - /// - /// # Examples - /// - /// ```sway - /// use sway_libs::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::zero(); - /// assert(ufp64.underlying() == 0); - /// } - /// ``` - pub fn underlying(self) -> u64 { - self.underlying - } -} - -impl core::ops::Eq for UFP64 { - fn eq(self, other: Self) -> bool { - self.underlying == other.underlying - } -} - -impl core::ops::Ord for UFP64 { - fn gt(self, other: Self) -> bool { - self.underlying > other.underlying - } - - fn lt(self, other: Self) -> bool { - self.underlying < other.underlying - } -} - -impl core::ops::Add for UFP64 { - /// Add a UFP64 to a UFP64. Panics on overflow. - fn add(self, other: Self) -> Self { - Self { - underlying: self.underlying + other.underlying, - } - } -} - -impl core::ops::Subtract for UFP64 { - /// Subtract a UFP64 from a UFP64. Panics of overflow. - fn subtract(self, other: Self) -> Self { - // If trying to subtract a larger number, panic. - assert(self.underlying >= other.underlying); - - Self { - underlying: self.underlying - other.underlying, - } - } -} - -impl core::ops::Multiply for UFP64 { - /// Multiply a UFP64 with a UFP64. Panics of overflow. - fn multiply(self, other: Self) -> Self { - let self_u128 = U128::from((0, self.underlying)); - let other_u128 = U128::from((0, other.underlying)); - - let self_multiply_other = self_u128 * other_u128; - let res_u128 = self_multiply_other >> 32; - if res_u128.upper() != 0 { - // panic on overflow - revert(0); - } - - Self { - underlying: res_u128.lower(), - } - } -} - -impl core::ops::Divide for UFP64 { - /// Divide a UFP64 by a UFP64. Panics if divisor is zero. - fn divide(self, divisor: Self) -> Self { - let zero = UFP64::zero(); - assert(divisor != zero); - - let denominator = U128::from((0, Self::denominator())); - // Conversion to U128 done to ensure no overflow happen - // and maximal precision is avaliable - // as it makes possible to multiply by the denominator in - // all cases - let self_u128 = U128::from((0, self.underlying)); - let divisor_u128 = U128::from((0, divisor.underlying)); - - // Multiply by denominator to ensure accuracy - let res_u128 = self_u128 * denominator / divisor_u128; - - if res_u128.upper() != 0 { - // panic on overflow - revert(0); - } - Self { - underlying: res_u128.lower(), - } - } -} - -impl UFP64 { - /// Creates UFP64 that corresponds to a unsigned integer. - /// - /// # Arguments - /// - /// * `uint`: [u64] - The unsigned number to become the underlying value for the `UFP64`. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(1); - /// assert(ufp64.underlying() == 4294967296); - /// } - /// ``` - pub fn from_uint(uint: u64) -> Self { - Self { - underlying: Self::denominator() * uint, - } - } -} - -impl UFP64 { - /// Takes the reciprocal (inverse) of a number, `1/x`. - /// - /// # Arguments - /// - /// * `number`: [UFP64] - The value to create the reciprocal from. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let recip = UFP64::recip(ufp64); - /// assert(recip.underlying() == 33554432); - /// } - /// ``` - pub fn recip(number: UFP64) -> Self { - let one = UFP64::from_uint(1); - - let res = one / number; - res - } - - /// Returns the integer part of `self`. - /// - /// # Additional Information - /// - /// This means that non-integer numbers are always truncated towards zero. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let trunc = ufp64.trunc(); - /// assert(trunc.underlying() == 0); - /// } - /// ``` - pub fn trunc(self) -> Self { - Self { - // first move to the right (divide by the denominator) - // to get rid of fractional part, than move to the - // left (multiply by the denominator), to ensure - // fixed-point structure - underlying: (self.underlying >> 32) << 32, - } - } -} - -impl UFP64 { - /// Returns the largest integer less than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let floor = ufp64.floor(); - /// assert(floor.underlying() == 0); - /// } - /// ``` - pub fn floor(self) -> Self { - return self.trunc(); - } - - /// Returns the fractional part of `self`. - /// - /// # Returns - /// - /// * [UFP64] - the newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let fract = ufp64.fract(); - /// assert(fract.underlying() == 0); - /// } - /// ``` - pub fn fract(self) -> Self { - Self { - // first move to the left (multiply by the denominator) - // to get rid of integer part, than move to the - // right (divide by the denominator), to ensure - // fixed-point structure - underlying: (self.underlying << 32) >> 32, - } - } -} - -impl UFP64 { - /// Returns the smallest integer greater than or equal to `self`. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let ceil = ufp64.ceil(); - /// assert(ceil.underlying() = 4294967296); - /// } - /// ``` - pub fn ceil(self) -> Self { - if self.fract().underlying != 0 { - let res = self.trunc() + UFP64::from_uint(1); - return res; - } - return self; - } -} - -impl UFP64 { - /// Returns the nearest integer to `self`. Round half-way cases away from zero. - /// - /// # Returns - /// - /// * [UFP64] - The newly created `UFP64` type. - /// - /// # Examples - /// - /// ```sway - /// use libraries::fixed_point::ufp64::UFP64; - /// - /// fn foo() { - /// let ufp64 = UFP64::from_uint(128); - /// let round = ufp64.round(); - /// assert(round.underlying() == 0); - /// } - /// ``` - pub fn round(self) -> Self { - let floor = self.floor(); - let ceil = self.ceil(); - let diff_self_floor = self - floor; - let diff_ceil_self = ceil - self; - - // Check if we are closer to the floor or to the ceiling - if diff_self_floor < diff_ceil_self { - return floor; - } else { - return ceil; - } - } -} - -impl Root for UFP64 { - /// Sqaure root for UFP64 - fn sqrt(self) -> Self { - let nominator_root = self.underlying.sqrt(); - // Need to multiply over 2 ^ 16, as the square root of the denominator - // is also taken and we need to ensure that the denominator is constant - let nominator = nominator_root << 16; - Self { - underlying: nominator, - } - } -} - -impl Exponent for UFP64 { - /// Exponent function. e ^ x - fn exp(exponent: Self) -> Self { - let one = UFP64::from_uint(1); - - // Coefficients in the Taylor series up to the seventh power - let p2 = UFP64::from(2147483648); // p2 == 1 / 2! - let p3 = UFP64::from(715827882); // p3 == 1 / 3! - let p4 = UFP64::from(178956970); // p4 == 1 / 4! - let p5 = UFP64::from(35791394); // p5 == 1 / 5! - let p6 = UFP64::from(5965232); // p6 == 1 / 6! - let p7 = UFP64::from(852176); // p7 == 1 / 7! - // Common technique to counter losing significant numbers in usual approximation - // Taylor series approximation of exponentiation function minus 1. The subtraction is done to deal with accuracy issues - let res_minus_1 = exponent + exponent * exponent * (p2 + exponent * (p3 + exponent * (p4 + exponent * (p5 + exponent * (p6 + exponent * p7))))); - let res = res_minus_1 + one; - res - } -} - -impl Power for UFP64 { - /// Power function. x ^ exponent - fn pow(self, exponent: u32) -> Self { - let demoninator_power = UFP64::denominator(); - let nominator_pow = U128::from((0, self.underlying)).pow(exponent); - // As we need to ensure the fixed point structure - // which means that the denominator is always 2 ^ 32 - // we need to delete the nominator by 2 ^ (32 * exponent - 1) - // - 1 is the formula is due to denominator need to stay 2 ^ 32 - let nominator = nominator_pow >> demoninator_power * (exponent.as_u64() - 1); - - if nominator.upper() != 0 { - // panic on overflow - revert(0); - } - Self { - underlying: nominator.lower(), - } - } -} diff --git a/libs/src/lib.sw b/libs/src/lib.sw index 135e370a..0996585b 100644 --- a/libs/src/lib.sw +++ b/libs/src/lib.sw @@ -2,7 +2,6 @@ library; pub mod asset; pub mod bytecode; -pub mod fixed_point; pub mod merkle; pub mod ownership; pub mod admin; @@ -10,3 +9,4 @@ pub mod pausable; pub mod queue; pub mod reentrancy; pub mod signed_integers; +pub mod upgradability; diff --git a/libs/src/signed_integers/common.sw b/libs/src/signed_integers/common.sw index 8fade82b..acd8fe7d 100644 --- a/libs/src/signed_integers/common.sw +++ b/libs/src/signed_integers/common.sw @@ -1,11 +1,15 @@ library; -/// Trait for the Two's Complement of a value. -pub trait TwosComplement { - /// Returns the two's complement of a value. +/// Wrapping (modular) negation. Computes -self, wrapping around at the boundary of the type. +pub trait WrappingNeg { + /// Negates a signed number. + /// + /// # Additional Information + /// + /// * The only case where such wrapping can occur is when one negates self::min(). In such a case, this function returns self::min() itself. /// /// # Returns /// /// * [Self] - The value as two's complement. - fn twos_complement(self) -> Self; + fn wrapping_neg(self) -> Self; } diff --git a/libs/src/signed_integers/i128.sw b/libs/src/signed_integers/i128.sw index a3f17899..fddcfbe3 100644 --- a/libs/src/signed_integers/i128.sw +++ b/libs/src/signed_integers/i128.sw @@ -1,7 +1,7 @@ library; -use std::u128::U128; -use ::signed_integers::common::TwosComplement; +use std::{convert::TryFrom, u128::U128}; +use ::signed_integers::common::WrappingNeg; use ::signed_integers::errors::Error; /// The 128-bit signed integer type. @@ -31,20 +31,11 @@ impl I128 { /// /// fn foo() { /// let zero = I128::indent(); - /// assert(zero == U128::from((1, 0))); + /// assert(zero == (U128::max() / (U128::from(0, 2)) - U128::from(0,1)); /// } /// ``` pub fn indent() -> U128 { - U128::from((1, 0)) - } -} - -impl From for I128 { - /// Helper function to get a signed number from with an underlying - fn from(value: U128) -> Self { - // as the minimal value of I128 is -I128::indent() (1 << 63) we should add I128::indent() (1 << 63) - let underlying: U128 = value + Self::indent(); - Self { underlying } + U128::from((9223372036854775808, 0)) } } @@ -64,6 +55,8 @@ impl core::ops::Ord for I128 { } } +impl core::ops::OrdEq for I128 {} + impl I128 { /// The size of this type in bits. /// @@ -165,7 +158,7 @@ impl I128 { /// /// # Returns /// - /// * [I128] - The newly created `I128` struct. + /// * [Option] - The newly created `I128` struct. /// /// # Examples /// @@ -175,13 +168,17 @@ impl I128 { /// /// fn foo() { /// let underlying = U128::from((1, 0)); - /// let i128 = I128::neg_from(underlying); + /// let i128 = I128::neg_try_from(underlying).unwrap(); /// assert(i128.underlying() == U128::from((0, 0))); /// } /// ``` - pub fn neg_from(value: U128) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: U128) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -189,7 +186,7 @@ impl I128 { /// /// # Additional Information /// - /// The zero value of I128 is U128::from((1, 0)). + /// The zero value of I128 is U128::from((9223372036854775808, 0)). /// /// # Returns /// @@ -269,7 +266,7 @@ impl I128 { /// /// fn foo() { /// let i128 = I128::zero(); - /// assert(i128.underlying() == U128::from((1, 0))); + /// assert(i128.underlying() == U128::from((9223372036854775808, 0))); /// } /// ``` pub fn underlying(self) -> U128 { @@ -342,10 +339,8 @@ impl core::ops::Multiply for I128 { /// Multiply a I128 with a I128. Panics of overflow. fn multiply(self, other: Self) -> Self { let mut res = Self::new(); - if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) + if self.underlying >= Self::indent() + && other.underlying >= Self::indent() { res = Self::from_uint( (self.underlying - Self::indent()) * (other.underlying - Self::indent()) + Self::indent(), @@ -356,16 +351,14 @@ impl core::ops::Multiply for I128 { res = Self::from_uint( (Self::indent() - self.underlying) * (Self::indent() - other.underlying) + Self::indent(), ); - } else if (self.underlying > Self::indent() - || self.underlying == Self::indent()) + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { res = Self::from_uint( Self::indent() - (self.underlying - Self::indent()) * (Self::indent() - other.underlying), ); } else if self.underlying < Self::indent() - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) + && other.underlying >= Self::indent() { res = Self::from_uint( Self::indent() - (other.underlying - Self::indent()) * (Self::indent() - self.underlying), @@ -379,48 +372,55 @@ impl core::ops::Subtract for I128 { /// Subtract a I128 from a I128. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res } } -impl TwosComplement for I128 { - fn twos_complement(self) -> Self { - if self.underlying == Self::indent() - || self.underlying > Self::indent() - { - return self; +impl WrappingNeg for I128 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(U128::from((0, 1))).unwrap() + } +} + +impl TryFrom for I128 { + fn try_from(value: U128) -> Option { + // as the minimal value of I128 is -I128::indent() (1 << 63) we should add I128::indent() (1 << 63) + if value < U128::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for U128 { + fn try_from(value: I128) -> Option { + if value >= I128::zero() { + Some(value.underlying - I128::indent()) + } else { + None } - let u_one = U128::from((0, 1)); - let res = I128::from_uint(!self.underlying + u_one); - res } } diff --git a/libs/src/signed_integers/i16.sw b/libs/src/signed_integers/i16.sw index ac5223b5..b3da7430 100644 --- a/libs/src/signed_integers/i16.sw +++ b/libs/src/signed_integers/i16.sw @@ -1,7 +1,8 @@ library; +use std::convert::TryFrom; use ::signed_integers::errors::Error; -use ::signed_integers::common::TwosComplement; +use ::signed_integers::common::WrappingNeg; /// The 16-bit signed integer type. /// @@ -37,15 +38,6 @@ impl I16 { } } -impl From for I16 { - /// Helper function to get a signed number from with an underlying - fn from(value: u16) -> Self { - // as the minimal value of I16 is -I16::indent() (1 << 15) we should add I16::indent() (1 << 15) - let underlying: u16 = value + Self::indent(); - Self { underlying } - } -} - impl core::ops::Eq for I16 { fn eq(self, other: Self) -> bool { self.underlying == other.underlying @@ -62,6 +54,8 @@ impl core::ops::Ord for I16 { } } +impl core::ops::OrdEq for I16 {} + impl I16 { /// The size of this type in bits. /// @@ -160,7 +154,7 @@ impl I16 { /// /// # Returns /// - /// * [I16] - The newly created `I16` struct. + /// * [Option] - The newly created `I16` struct. /// /// # Examples /// @@ -169,13 +163,17 @@ impl I16 { /// /// fn foo() { /// let underlying = 1u16; - /// let i16 = I16::neg_from(underlying); + /// let i16 = I16::neg_try_from(underlying).unwrap(); /// assert(i16.underlying() == 32767u16) /// } /// ``` - pub fn neg_from(value: u16) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: u16) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -362,41 +360,55 @@ impl core::ops::Subtract for I16 { /// Subtract a I16 from a I16. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if self.underlying >= Self::indent() - && other.underlying >= Self::indent() - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if self.underlying >= Self::indent() - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && other.underlying >= Self::indent() - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res } } -impl TwosComplement for I16 { - fn twos_complement(self) -> Self { - if self.underlying >= Self::indent() { - return self; +impl WrappingNeg for I16 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(1u16).unwrap() + } +} + +impl TryFrom for I16 { + fn try_from(value: u16) -> Option { + // as the minimal value of I16 is -I16::indent() (1 << 15) we should add I16::indent() (1 << 15) + if value < u16::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for u16 { + fn try_from(value: I16) -> Option { + if value >= I16::zero() { + Some(value.underlying - I16::indent()) + } else { + None } - let res = Self::from_uint(!self.underlying + 1u16); - res } } diff --git a/libs/src/signed_integers/i256.sw b/libs/src/signed_integers/i256.sw index 736f267e..92d35bbc 100644 --- a/libs/src/signed_integers/i256.sw +++ b/libs/src/signed_integers/i256.sw @@ -1,6 +1,7 @@ library; -use ::signed_integers::common::TwosComplement; +use std::convert::TryFrom; +use ::signed_integers::common::WrappingNeg; use ::signed_integers::errors::Error; /// The 256-bit signed integer type. @@ -19,7 +20,7 @@ impl I256 { /// /// # Additional Information /// - /// The zero value for I256 is 0x0000000000000000000000000000001000000000000000000000000000000000u256. + /// The zero value for I256 is 0x8000000000000000000000000000000000000000000000000000000000000000u256. /// /// # Returns /// @@ -32,22 +33,11 @@ impl I256 { /// /// fn foo() { /// let zero = I256::indent(); - /// assert(zero == 0x0000000000000000000000000000001000000000000000000000000000000000u256); + /// assert(zero == 0x8000000000000000000000000000000000000000000000000000000000000000u256); /// } /// ``` pub fn indent() -> u256 { - let parts = (0, 1, 0, 0); - asm(r1: parts) { - r1: u256 - } - } -} - -impl From for I256 { - fn from(value: u256) -> Self { - // as the minimal value of I256 is -I256::indent() (1 << 63) we should add I256::indent() (1 << 63) - let underlying = value + Self::indent(); - Self { underlying } + 0x8000000000000000000000000000000000000000000000000000000000000000u256 } } @@ -67,6 +57,8 @@ impl core::ops::Ord for I256 { } } +impl core::ops::OrdEq for I256 {} + impl I256 { /// The size of this type in bits. /// @@ -81,11 +73,11 @@ impl I256 { /// /// fn foo() { /// let bits = I256::bits(); - /// assert(bits == 128); + /// assert(bits == 256); /// } /// ``` pub fn bits() -> u64 { - 128 + 256 } /// Helper function to get a signed number from with an underlying. @@ -165,7 +157,7 @@ impl I256 { /// /// # Returns /// - /// * [I256] - The newly created `I256` struct. + /// * [Option] - The newly created `I256` struct. /// /// # Examples /// @@ -173,14 +165,18 @@ impl I256 { /// use sway_libs::signed_integers::i256::I256; /// /// fn foo() { - /// let underlying = 0x0000000000000000000000000000001000000000000000000000000000000000u256; - /// let i256 = I256::neg_from(underlying); - /// assert(i256.underlying() == 0x0000000000000000000000000000000000000000000000000000000000000000u256); + /// let underlying = 0x0000000000000000000000000000000000000000000000000000000000000000u256; + /// let i256 = I256::neg_try_from(underlying).unwrap(); + /// assert(i256.underlying() == 0x8000000000000000000000000000000000000000000000000000000000000000u256); /// } /// ``` - pub fn neg_from(value: u256) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: u256) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -188,7 +184,7 @@ impl I256 { /// /// # Additional Information /// - /// The zero value of I256 is 0x0000000000000000000000000000001000000000000000000000000000000000u256. + /// The zero value of I256 is 0x8000000000000000000000000000000000000000000000000000000000000000u256. /// /// # Returns /// @@ -201,7 +197,7 @@ impl I256 { /// /// fn foo() { /// let i256 = I256::new(); - /// assert(i256.underlying() == 0x0000000000000000000000000000001000000000000000000000000000000000u256); + /// assert(i256.underlying() == 0x8000000000000000000000000000000000000000000000000000000000000000u256); /// } /// ``` pub fn new() -> Self { @@ -223,7 +219,7 @@ impl I256 { /// /// fn foo() { /// let i256 = I256::zero(); - /// assert(i256.underlying() == 0x0000000000000000000000000000001000000000000000000000000000000000u256); + /// assert(i256.underlying() == 0x8000000000000000000000000000000000000000000000000000000000000000u256); /// } /// ``` pub fn zero() -> Self { @@ -265,7 +261,7 @@ impl I256 { /// /// fn foo() { /// let i256 = I256::zero(); - /// assert(i256.underlying() == 0x0000000000000000000000000000001000000000000000000000000000000000u256); + /// assert(i256.underlying() == 0x8000000000000000000000000000000000000000000000000000000000000000u256); /// } /// ``` pub fn underlying(self) -> u256 { @@ -277,18 +273,17 @@ impl core::ops::Add for I256 { /// Add a I256 to a I256. Panics on overflow. fn add(self, other: Self) -> Self { // subtract 1 << 63 to avoid double move + let indent = Self::indent(); let mut res = Self::new(); - if (self.underlying > Self::indent() || self.underlying == Self::indent()) { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying) // subtract 1 << 31 to avoid double move - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); - } else if self.underlying < Self::indent() - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) + if (self.underlying > indent || self.underlying == indent) { + res = Self::from_uint(self.underlying - indent + other.underlying) // subtract 1 << 31 to avoid double move + } else if self.underlying < indent && other.underlying < indent { + res = Self::from_uint(self.underlying + other.underlying - indent); + } else if self.underlying < indent + && (other.underlying > indent + || other.underlying == indent) { - res = Self::from_uint(other.underlying - Self::indent() + self.underlying); + res = Self::from_uint(other.underlying - indent + self.underlying); } res } @@ -299,35 +294,21 @@ impl core::ops::Divide for I256 { fn divide(self, divisor: Self) -> Self { require(divisor != Self::new(), Error::ZeroDivisor); let mut res = Self::new(); - let self_ge_indent = self.underlying > Self::indent() || self.underlying == Self::indent(); - let divisor_gt_indent = divisor.underlying > Self::indent(); + let indent = Self::indent(); + + let self_ge_indent = self.underlying > indent || self.underlying == indent; + let divisor_gt_indent = divisor.underlying > indent; if self_ge_indent && divisor_gt_indent { - res = Self::from_uint( - (self.underlying - Self::indent()) / (divisor - .underlying - Self::indent()) + Self::indent(), - ); - } else if self.underlying < Self::indent() - && divisor.underlying < Self::indent() - { - res = Self::from_uint( - (Self::indent() - self.underlying) / (Self::indent() - divisor - .underlying) + Self::indent(), - ); - } else if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && divisor.underlying < Self::indent() - { - res = Self::from_uint( - Self::indent() - (self.underlying - Self::indent()) / (Self::indent() - divisor - .underlying), - ); - } else if self.underlying < Self::indent() - && divisor.underlying > Self::indent() + res = Self::from_uint((self.underlying - indent) / (divisor.underlying - indent) + indent); + } else if self.underlying < indent && divisor.underlying < indent { + res = Self::from_uint((indent - self.underlying) / (indent - divisor.underlying) + indent); + } else if (self.underlying > indent + || self.underlying == indent) + && divisor.underlying < indent { - res = Self::from_uint( - Self::indent() - (Self::indent() - self.underlying) / (divisor - .underlying - Self::indent()), - ); + res = Self::from_uint(indent - (self.underlying - indent) / (indent - divisor.underlying)); + } else if self.underlying < indent && divisor.underlying > indent { + res = Self::from_uint(indent - (indent - self.underlying) / (divisor.underlying - indent)); } res } @@ -337,10 +318,8 @@ impl core::ops::Multiply for I256 { /// Multiply a I256 with a I256. Panics of overflow. fn multiply(self, other: Self) -> Self { let mut res = Self::new(); - if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) + if self.underlying >= Self::indent() + && other.underlying >= Self::indent() { res = Self::from_uint( (self.underlying - Self::indent()) * (other.underlying - Self::indent()) + Self::indent(), @@ -351,16 +330,14 @@ impl core::ops::Multiply for I256 { res = Self::from_uint( (Self::indent() - self.underlying) * (Self::indent() - other.underlying) + Self::indent(), ); - } else if (self.underlying > Self::indent() - || self.underlying == Self::indent()) + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { res = Self::from_uint( Self::indent() - (self.underlying - Self::indent()) * (Self::indent() - other.underlying), ); } else if self.underlying < Self::indent() - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) + && other.underlying >= Self::indent() { res = Self::from_uint( Self::indent() - (other.underlying - Self::indent()) * (Self::indent() - self.underlying), @@ -374,49 +351,55 @@ impl core::ops::Subtract for I256 { /// Subtract a I256 from a I256. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - let q = other.underlying - Self::indent(); - res = Self::from_uint(self.underlying - q); + res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if (self.underlying > Self::indent() - || self.underlying == Self::indent()) - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && (other.underlying > Self::indent() - || other.underlying == Self::indent()) - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res } } -impl TwosComplement for I256 { - fn twos_complement(self) -> Self { - if self.underlying == Self::indent() - || self.underlying > Self::indent() - { - return self; +impl WrappingNeg for I256 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(0x0000000000000000000000000000000000000000000000000000000000000001u256).unwrap() + } +} + +impl TryFrom for I256 { + fn try_from(value: u256) -> Option { + // as the minimal value of I256 is -I256::indent() (1 << 63) we should add I256::indent() (1 << 63) + if value < u256::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for u256 { + fn try_from(value: I256) -> Option { + if value >= I256::zero() { + Some(value.underlying - I256::indent()) + } else { + None } - let u_one = 0x0000000000000000000000000000000000000000000000000000000000000001u256; - let res = I256::from_uint(!self.underlying + u_one); - res } } diff --git a/libs/src/signed_integers/i32.sw b/libs/src/signed_integers/i32.sw index a224a2ec..1e94e8ee 100644 --- a/libs/src/signed_integers/i32.sw +++ b/libs/src/signed_integers/i32.sw @@ -1,6 +1,7 @@ library; -use ::signed_integers::common::TwosComplement; +use std::convert::TryFrom; +use ::signed_integers::common::WrappingNeg; use ::signed_integers::errors::Error; /// The 32-bit signed integer type. @@ -37,14 +38,6 @@ impl I32 { } } -impl From for I32 { - fn from(value: u32) -> Self { - // as the minimal value of I32 is 2147483648 (1 << 31) we should add I32::indent() (1 << 31) - let underlying = value + Self::indent(); - Self { underlying } - } -} - impl core::ops::Eq for I32 { fn eq(self, other: Self) -> bool { self.underlying == other.underlying @@ -61,6 +54,8 @@ impl core::ops::Ord for I32 { } } +impl core::ops::OrdEq for I32 {} + impl I32 { /// The size of this type in bits. /// @@ -159,7 +154,7 @@ impl I32 { /// /// # Returns /// - /// * [I32] - The newly created `I32` struct. + /// * [Option] - The newly created `I32` struct. /// /// # Examples /// @@ -168,13 +163,17 @@ impl I32 { /// /// fn foo() { /// let underlying = 1u32; - /// let i32 = I32::neg_from(underlying); + /// let i32 = I32::neg_try_from(underlying).unwrap(); /// assert(i32.underlying() == 2147483647u32) /// } /// ``` - pub fn neg_from(value: u32) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: u32) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -290,29 +289,21 @@ impl core::ops::Subtract for I32 { /// Subtract a I32 from a I32. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if self.underlying >= Self::indent() - && other.underlying >= Self::indent() - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if self.underlying >= Self::indent() - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && other.underlying >= Self::indent() - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res @@ -390,12 +381,34 @@ impl core::ops::Divide for I32 { } } -impl TwosComplement for I32 { - fn twos_complement(self) -> Self { - if self.underlying >= Self::indent() { - return self; +impl WrappingNeg for I32 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(1u32).unwrap() + } +} + +impl TryFrom for I32 { + fn try_from(value: u32) -> Option { + // as the minimal value of I32 is 2147483648 (1 << 31) we should add I32::indent() (1 << 31) + if value < u32::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for u32 { + fn try_from(value: I32) -> Option { + if value >= I32::zero() { + Some(value.underlying - I32::indent()) + } else { + None } - let res = Self::from_uint(!self.underlying + 1u32); - res } } diff --git a/libs/src/signed_integers/i64.sw b/libs/src/signed_integers/i64.sw index 30ffb07f..3b8c24c4 100644 --- a/libs/src/signed_integers/i64.sw +++ b/libs/src/signed_integers/i64.sw @@ -1,6 +1,7 @@ library; -use ::signed_integers::common::TwosComplement; +use std::convert::TryFrom; +use ::signed_integers::common::WrappingNeg; use ::signed_integers::errors::Error; /// The 64-bit signed integer type. @@ -37,14 +38,6 @@ impl I64 { } } -impl From for I64 { - fn from(value: u64) -> Self { - // as the minimal value of I64 is -I64::indent() (1 << 63) we should add I64::indent() (1 << 63) - let underlying = value + Self::indent(); - Self { underlying } - } -} - impl core::ops::Eq for I64 { fn eq(self, other: Self) -> bool { self.underlying == other.underlying @@ -61,6 +54,8 @@ impl core::ops::Ord for I64 { } } +impl core::ops::OrdEq for I64 {} + impl I64 { /// The size of this type in bits. /// @@ -159,7 +154,7 @@ impl I64 { /// /// # Returns /// - /// * [I64] - The newly created `I64` struct. + /// * [Option] - The newly created `I64` struct. /// /// # Examples /// @@ -168,13 +163,17 @@ impl I64 { /// /// fn foo() { /// let underlying = 1u64; - /// let i64 = I64::neg_from(underlying); + /// let i64 = I64::neg_try_from(underlying).unwrap(); /// assert(i64.underlying() == 9223372036854775807u64); /// } /// ``` - pub fn neg_from(value: u64) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: u64) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -291,29 +290,21 @@ impl core::ops::Subtract for I64 { /// Subtract a I64 from a I64. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if self.underlying >= Self::indent() - && other.underlying >= Self::indent() - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if self.underlying >= Self::indent() - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && other.underlying >= Self::indent() - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res @@ -391,12 +382,34 @@ impl core::ops::Divide for I64 { } } -impl TwosComplement for I64 { - fn twos_complement(self) -> Self { - if self.underlying >= Self::indent() { - return self; +impl WrappingNeg for I64 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(1).unwrap() + } +} + +impl TryFrom for I64 { + fn try_from(value: u64) -> Option { + // as the minimal value of I64 is -I64::indent() (1 << 63) we should add I64::indent() (1 << 63) + if value < u64::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for u64 { + fn try_from(value: I64) -> Option { + if value >= I64::zero() { + Some(value.underlying - I64::indent()) + } else { + None } - let res = Self::from_uint(!self.underlying + 1); - res } } diff --git a/libs/src/signed_integers/i8.sw b/libs/src/signed_integers/i8.sw index bf5f5dc2..37b9938a 100644 --- a/libs/src/signed_integers/i8.sw +++ b/libs/src/signed_integers/i8.sw @@ -1,7 +1,8 @@ library; +use std::convert::TryFrom; use ::signed_integers::errors::Error; -use ::signed_integers::common::TwosComplement; +use ::signed_integers::common::WrappingNeg; /// The 8-bit signed integer type. /// @@ -37,14 +38,6 @@ impl I8 { } } -impl From for I8 { - fn from(value: u8) -> Self { - // as the minimal value of I8 is -I8::indent() (1 << 7) we should add I8::indent() (1 << 7) - let underlying: u8 = value + Self::indent(); - Self { underlying } - } -} - impl core::ops::Eq for I8 { fn eq(self, other: Self) -> bool { self.underlying == other.underlying @@ -61,6 +54,8 @@ impl core::ops::Ord for I8 { } } +impl core::ops::OrdEq for I8 {} + impl I8 { /// The size of this type in bits. /// @@ -159,7 +154,7 @@ impl I8 { /// /// # Returns /// - /// * [I8] - The newly created `I8` struct. + /// * [Option] - The newly created `I8` struct. /// /// # Examples /// @@ -168,13 +163,17 @@ impl I8 { /// /// fn foo() { /// let underlying = 1u8; - /// let i8 = I8::neg_from(underlying); + /// let i8 = I8::neg_try_from(underlying); /// assert(i8.underlying() == 127u8); /// } /// ``` - pub fn neg_from(value: u8) -> Self { - Self { - underlying: Self::indent() - value, + pub fn neg_try_from(value: u8) -> Option { + if value <= Self::indent() { + Some(Self { + underlying: Self::indent() - value, + }) + } else { + None } } @@ -361,41 +360,55 @@ impl core::ops::Subtract for I8 { /// Subtract a I8 from a I8. Panics of overflow. fn subtract(self, other: Self) -> Self { let mut res = Self::new(); - if self.underlying >= Self::indent() - && other.underlying >= Self::indent() - { + if self.underlying >= Self::indent() && other.underlying >= Self::indent() { // Both Positive if self.underlying > other.underlying { res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); } - } else if self.underlying >= Self::indent() - && other.underlying < Self::indent() - { - res = Self::from_uint(self.underlying - Self::indent() + other.underlying); - } else if self.underlying < Self::indent() - && other.underlying >= Self::indent() - { + } else if self.underlying >= Self::indent() && other.underlying < Self::indent() { // Self Positive, Other Negative + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying >= Self::indent() { // Self Negative, Other Positive res = Self::from_uint(self.underlying - (other.underlying - Self::indent())); - } else if self.underlying < Self::indent() - && other.underlying < Self::indent() - { - if self.underlying < other.underlying { - res = Self::from_uint(other.underlying - self.underlying + Self::indent()); + } else if self.underlying < Self::indent() && other.underlying < Self::indent() { // Both Negative + if self.underlying > other.underlying { + res = Self::from_uint(self.underlying - other.underlying + Self::indent()); } else { - res = Self::from_uint(self.underlying + other.underlying - Self::indent()); + res = Self::from_uint((self.underlying + Self::indent()) - other.underlying); } } res } } -impl TwosComplement for I8 { - fn twos_complement(self) -> Self { - if self.underlying >= Self::indent() { - return self; +impl WrappingNeg for I8 { + fn wrapping_neg(self) -> Self { + if self == self::min() { + return self::min() + } + self * Self::neg_try_from(1u8).unwrap() + } +} + +impl TryFrom for I8 { + fn try_from(value: u8) -> Option { + // as the minimal value of I8 is -I8::indent() (1 << 7) we should add I8::indent() (1 << 7) + if value < u8::max() - Self::indent() { + Some(Self { + underlying: value + Self::indent(), + }) + } else { + None + } + } +} + +impl TryFrom for u8 { + fn try_from(value: I8) -> Option { + if value >= I8::zero() { + Some(value.underlying - I8::indent()) + } else { + None } - let res = Self::from_uint(!self.underlying + 1u8); - res } } diff --git a/libs/src/upgradability.sw b/libs/src/upgradability.sw new file mode 100644 index 00000000..829ed7f6 --- /dev/null +++ b/libs/src/upgradability.sw @@ -0,0 +1,189 @@ +library; + +pub mod errors; +pub mod events; + +use ::upgradability::{errors::SetProxyOwnerError, events::{ProxyOwnerSet, ProxyTargetSet}}; +use std::{auth::msg_sender, storage::storage_api::{read, write}}; +use standards::{src14::SRC14_TARGET_STORAGE, src5::{AccessError, State}}; + +/// Returns the proxy target. +/// +/// # Returns +/// +/// * [Option] - The ContractId of the proxy target. +/// +/// # Number of Storage Accesses +/// +/// * Reads: `1` +/// +/// # Examples +/// +/// ```sway +/// use sway_libs::upgradability::_proxy_target; +/// +/// fn foo() { +/// let stored_proxy_target = _proxy_target(); +/// } +/// ``` +#[storage(read)] +pub fn _proxy_target() -> Option { + let proxy_target_key = StorageKey::new(SRC14_TARGET_STORAGE, 0, SRC14_TARGET_STORAGE); + proxy_target_key.read() +} + +/// Change the target contract of a proxy contract. +/// +/// # Arguments +/// +/// * `new_target`: [ContractId] - The new proxy contract to which all fallback calls will be passed. +/// +/// # Number of Storage Accesses +/// +/// * Writes: `1` +/// +/// # Examples +/// +/// ```sway +/// use sway_libs::upgradability::{_proxy_target, _set_proxy_target}; +/// +/// fn foo() { +/// assert(_proxy_target() == None); +/// +/// let new_target = ContractId::zero(); +/// _set_proxy_target(new_target); +/// +/// assert(_proxy_target() == Some(new_target)); +/// } +/// ``` +#[storage(write)] +pub fn _set_proxy_target(new_target: ContractId) { + let proxy_target_key = StorageKey::new(SRC14_TARGET_STORAGE, 0, SRC14_TARGET_STORAGE); + proxy_target_key.write(Some(new_target)); + + log(ProxyTargetSet { new_target }); +} + +/// Returns the owner of the proxy. +/// +/// # Arguments +/// +/// * `proxy_owner_storage_key`: [StorageKey] - The storage key of the stored proxy owner. +/// +/// # Returns +/// +/// * [State] - The state of the proxy ownership. +/// +/// # Number of Storage Accesses +/// +/// * Reads: `1` +/// +/// # Examples +/// +/// ```sway +/// use sway_libs::upgradability::_proxy_owner; +/// +/// storage { +/// proxy_owner: State = State::Uninitialized, +/// } +/// +/// fn foo() { +/// let stored_proxy_owner = _proxy_owner(storage.proxy_owner); +/// } +/// ``` +#[storage(read)] +pub fn _proxy_owner(proxy_owner_storage_key: StorageKey) -> State { + proxy_owner_storage_key.read() +} + +/// Ensures that the sender is the proxy owner. +/// +/// # Arguments +/// +/// * `proxy_owner_storage_key`: [StorageKey] - The storage key of the stored proxy owner. +/// +/// # Reverts +/// +/// * When the sender is not the proxy owner. +/// +/// # Number of Storage Accesses +/// +/// * Reads: `1` +/// +/// # Examples +/// +/// ```sway +/// use sway_libs::ownership::only_proxy_owner; +/// +/// storage { +/// proxy_owner: State = State::Uninitialized, +/// } +/// +/// fn foo() { +/// only_proxy_owner(storage.proxy_owner); +/// // Do stuff here if the sender is the proxy owner +/// } +/// ``` +#[storage(read)] +pub fn only_proxy_owner(proxy_owner_storage_key: StorageKey) { + require( + _proxy_owner(proxy_owner_storage_key) == State::Initialized(msg_sender().unwrap()), + AccessError::NotOwner, + ); +} + +/// Change proxy ownership to the passed State. +/// +/// # Additional Information +/// +/// This function can be used to transfer ownership between Identities or to revoke ownership. +/// +/// # Arguments +/// +/// * `new_proxy_owner`: [State] - The new state of the proxy ownership. +/// * `proxy_owner_storage_key`: [StorageKey] - The storage key of the stored proxy owner. +/// +/// # Reverts +/// +/// * When the sender is not the proxy owner. +/// * When the new state of the proxy ownership is Uninitialized. +/// +/// # Number of Storage Accesses +/// +/// * Writes: `1` +/// +/// # Examples +/// +/// ```sway +/// use sway_libs::upgradability::{_proxy_owner, _set_proxy_owner}; +/// +/// storage { +/// proxy_owner: State = State::Uninitialized, +/// } +/// +/// fn foo(new_owner: Identity) { +/// assert(_proxy_owner(storage.proxy_owner) == State::Initialized(Identity::Address(Address::zero())); +/// +/// let new_proxy_owner = State::Initialized(new_owner); +/// _set_proxy_owner(new_proxy_owner, storage.proxy_owner); +/// +/// assert(_proxy_owner(storage.proxy_owner) == State::Initialized(new_owner)); +/// } +/// ``` +#[storage(write)] +pub fn _set_proxy_owner( + new_proxy_owner: State, + proxy_owner_storage_key: StorageKey, +) { + only_proxy_owner(proxy_owner_storage_key); + require( + new_proxy_owner != State::Uninitialized, + SetProxyOwnerError::CannotUninitialize, + ); + + proxy_owner_storage_key.write(new_proxy_owner); + + log(ProxyOwnerSet { + new_proxy_owner, + }); +} diff --git a/libs/src/upgradability/errors.sw b/libs/src/upgradability/errors.sw new file mode 100644 index 00000000..3bc00cbc --- /dev/null +++ b/libs/src/upgradability/errors.sw @@ -0,0 +1,7 @@ +library; + +/// Error log for when setting proxy owner is denied. +pub enum SetProxyOwnerError { + /// Emitted when the owner state is being uninitialized. + CannotUninitialize: (), +} diff --git a/libs/src/upgradability/events.sw b/libs/src/upgradability/events.sw new file mode 100644 index 00000000..75e60181 --- /dev/null +++ b/libs/src/upgradability/events.sw @@ -0,0 +1,15 @@ +library; + +use standards::src5::State; + +/// Logged when ownership is a new proxy target is set. +pub struct ProxyTargetSet { + /// The new target contract. + pub new_target: ContractId, +} + +/// Logged when ownership is a new proxy owner is set. +pub struct ProxyOwnerSet { + /// The new ownership state. + pub new_proxy_owner: State, +} diff --git a/tests/Cargo.toml b/tests/Cargo.toml index ad14b574..fcdee262 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -10,7 +10,10 @@ fuel-merkle = { version = "0.49.0" } fuels = { version = "0.62.0", features = ["fuel-core-lib"] } sha2 = { version = "0.10" } tokio = { version = "1.12", features = ["rt", "macros"] } -rand = { version = "0.8.5", default-features = false, features = ["std_rng", "getrandom"] } +rand = { version = "0.8.5", default-features = false, features = [ + "std_rng", + "getrandom", +] } fuel-tx = { version = "0.43.1" } [[test]] diff --git a/tests/Forc.lock b/tests/Forc.lock new file mode 100644 index 00000000..010d053f --- /dev/null +++ b/tests/Forc.lock @@ -0,0 +1,241 @@ +[[package]] +name = "admin_test" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "bytecode_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "complex_contract" +source = "member" +dependencies = ["std"] + +[[package]] +name = "core" +source = "path+from-root-E19CE48B3E858B72" + +[[package]] +name = "i128_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i128_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i16_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i16_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i256_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i256_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i32_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i32_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i64_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i64_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i8_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "i8_wrapping_neg_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "merkle_proof_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "native_asset_lib" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "ownership_test" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", + "sway_libs", +] + +[[package]] +name = "pausable_test" +source = "member" +dependencies = [ + "std", + "sway_libs", +] + +[[package]] +name = "reentrancy_attack_helper_abi" +source = "member" +dependencies = ["std"] + +[[package]] +name = "reentrancy_attack_helper_contract" +source = "member" +dependencies = [ + "reentrancy_attack_helper_abi", + "reentrancy_target_abi", + "std", +] + +[[package]] +name = "reentrancy_attacker_abi" +source = "member" +dependencies = ["std"] + +[[package]] +name = "reentrancy_attacker_contract" +source = "member" +dependencies = [ + "reentrancy_attack_helper_abi", + "reentrancy_attacker_abi", + "reentrancy_target_abi", + "std", +] + +[[package]] +name = "reentrancy_target_abi" +source = "member" +dependencies = ["std"] + +[[package]] +name = "reentrancy_target_contract" +source = "member" +dependencies = [ + "reentrancy_attacker_abi", + "reentrancy_target_abi", + "std", + "sway_libs", +] + +[[package]] +name = "simple_contract" +source = "member" +dependencies = ["std"] + +[[package]] +name = "simple_predicate" +source = "member" +dependencies = ["std"] + +[[package]] +name = "standards" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18" +dependencies = ["std"] + +[[package]] +name = "standards" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.1#e2d5ac40a1d11a9e38e0a662d35141076515319f" +dependencies = ["std"] + +[[package]] +name = "std" +source = "git+https://github.com/fuellabs/sway?tag=v0.60.0#2f0392ee35a1e4dd80bd8034962d5b4083dfb8b6" +dependencies = ["core"] + +[[package]] +name = "sway_libs" +source = "path+from-root-8E8363697A2C7D80" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.0#348f7175df4c012b23c86cdb18aab79025ca1f18", + "std", +] + +[[package]] +name = "upgradability_test" +source = "member" +dependencies = [ + "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.5.1#e2d5ac40a1d11a9e38e0a662d35141076515319f", + "std", + "sway_libs", +] diff --git a/tests/Forc.toml b/tests/Forc.toml index 080dc843..0f4249e4 100644 --- a/tests/Forc.toml +++ b/tests/Forc.toml @@ -5,29 +5,6 @@ members = [ "./src/bytecode/test_artifacts/simple_contract", "./src/bytecode/test_artifacts/complex_contract", "./src/bytecode/test_contract", - "./src/fixed_point/ufp32_div_test", - "./src/fixed_point/ufp32_exp_test", - "./src/fixed_point/ufp32_mul_test", - "./src/fixed_point/ufp32_pow_test", - "./src/fixed_point/ufp32_root_test", - "./src/fixed_point/ufp32_test", - "./src/fixed_point/ufp64_div_test", - "./src/fixed_point/ufp64_exp_test", - "./src/fixed_point/ufp64_mul_test", - "./src/fixed_point/ufp64_pow_test", - "./src/fixed_point/ufp64_root_test", - "./src/fixed_point/ufp64_test", - "./src/fixed_point/ufp128_div_test", - "./src/fixed_point/ufp128_test", - "./src/fixed_point/ifp64_div_test", - "./src/fixed_point/ifp64_exp_test", - "./src/fixed_point/ifp64_mul_test", - "./src/fixed_point/ifp64_pow_test", - "./src/fixed_point/ifp64_test", - "./src/fixed_point/ifp128_div_test", - "./src/fixed_point/ifp128_test", - "./src/fixed_point/ifp256_div_test", - "./src/fixed_point/ifp256_test", "./src/merkle_proof", "./src/native_asset", "./src/pausable", @@ -44,8 +21,11 @@ members = [ "./src/signed_integers/signed_i64", "./src/signed_integers/signed_i128", "./src/signed_integers/signed_i256", - "./src/signed_integers/signed_i8_twos_complement", - "./src/signed_integers/signed_i16_twos_complement", - "./src/signed_integers/signed_i32_twos_complement", - "./src/signed_integers/signed_i64_twos_complement", + "./src/signed_integers/signed_i8_wrapping_neg", + "./src/signed_integers/signed_i16_wrapping_neg", + "./src/signed_integers/signed_i32_wrapping_neg", + "./src/signed_integers/signed_i64_wrapping_neg", + "./src/signed_integers/signed_i128_wrapping_neg", + "./src/signed_integers/signed_i256_wrapping_neg", + "./src/upgradability", ] diff --git a/tests/src/bytecode/tests/functions/compute_bytecode_root.rs b/tests/src/bytecode/tests/functions/compute_bytecode_root.rs index 7fddff4a..f11ed029 100644 --- a/tests/src/bytecode/tests/functions/compute_bytecode_root.rs +++ b/tests/src/bytecode/tests/functions/compute_bytecode_root.rs @@ -64,3 +64,20 @@ mod success { assert_eq!(result_bytecode_root, predicate_bytecode_root); } } + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, _wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + + // Call the contract and compute the bytecode root + let _result_bytecode_root = + compute_bytecode_root(&test_contract_instance, empty_bytecode).await; + } +} diff --git a/tests/src/bytecode/tests/functions/compute_bytecode_root_with_configurables.rs b/tests/src/bytecode/tests/functions/compute_bytecode_root_with_configurables.rs index fe69a57d..98ad1d24 100644 --- a/tests/src/bytecode/tests/functions/compute_bytecode_root_with_configurables.rs +++ b/tests/src/bytecode/tests/functions/compute_bytecode_root_with_configurables.rs @@ -101,3 +101,25 @@ mod success { assert_eq!(result_bytecode_root, predicate_bytecode_root); } } + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, _wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + let my_configurables: Vec<(u64, Vec)> = Vec::new(); + + // Call the contract and compute the bytecode root + let _result_bytecode_root = compute_bytecode_root_with_configurables( + &test_contract_instance, + empty_bytecode, + my_configurables, + ) + .await; + } +} diff --git a/tests/src/bytecode/tests/functions/compute_predicate_address.rs b/tests/src/bytecode/tests/functions/compute_predicate_address.rs index 715974f3..b1090bd7 100644 --- a/tests/src/bytecode/tests/functions/compute_predicate_address.rs +++ b/tests/src/bytecode/tests/functions/compute_predicate_address.rs @@ -25,3 +25,20 @@ mod success { assert_eq!(result_address, predicate_instance.address().into()); } } + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, _wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + + // Call the contract and compute the address + let _result_address = + compute_predicate_address(&test_contract_instance, empty_bytecode).await; + } +} diff --git a/tests/src/bytecode/tests/functions/compute_predicate_address_with_configurables.rs b/tests/src/bytecode/tests/functions/compute_predicate_address_with_configurables.rs index f3f47445..24ce883e 100644 --- a/tests/src/bytecode/tests/functions/compute_predicate_address_with_configurables.rs +++ b/tests/src/bytecode/tests/functions/compute_predicate_address_with_configurables.rs @@ -37,3 +37,25 @@ mod success { assert_eq!(result_address, predicate_instance.address().into()); } } + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + let my_configurables: Vec<(u64, Vec)> = Vec::new(); + + // Call the contract and compute the address + let _result_address = compute_predicate_address_with_configurables( + &test_contract_instance, + empty_bytecode, + my_configurables, + ) + .await; + } +} diff --git a/tests/src/bytecode/tests/functions/swap_configurables.rs b/tests/src/bytecode/tests/functions/swap_configurables.rs index 61677088..fdd820f8 100644 --- a/tests/src/bytecode/tests/functions/swap_configurables.rs +++ b/tests/src/bytecode/tests/functions/swap_configurables.rs @@ -135,3 +135,28 @@ mod success { spend_predicate(predicate_instance, wallet).await; } } + +mod failure { + use super::*; + + #[tokio::test] + #[should_panic] + async fn able_to_buffer_overflow() { + let (test_contract_instance, wallet) = test_contract_instance().await; + let (_contract_offset, _predicate_offset, config_value) = defaults(); + + // Get the bytecode for the contract + let file_bytecode = simple_contract_bytecode(); + + // Build the configurable changes + let my_configurables = build_simple_configurables(file_bytecode.len() as u64, config_value); + + // Call the contract to swap the configurables + let result_bytecode = swap_configurables( + &test_contract_instance, + file_bytecode.clone(), + my_configurables.clone(), + ) + .await; + } +} diff --git a/tests/src/bytecode/tests/functions/verify_contract_bytecode.rs b/tests/src/bytecode/tests/functions/verify_contract_bytecode.rs index dcfc3553..79a208e4 100644 --- a/tests/src/bytecode/tests/functions/verify_contract_bytecode.rs +++ b/tests/src/bytecode/tests/functions/verify_contract_bytecode.rs @@ -74,4 +74,23 @@ mod revert { ) .await; } + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + + // Deploy the new simple contract with the bytecode that contains the changes + let (simple_contract_instance, id) = deploy_simple_contract_from_file(wallet.clone()).await; + + verify_simple_contract_bytecode( + &test_contract_instance, + empty_bytecode, + id, + simple_contract_instance, + ) + .await; + } } diff --git a/tests/src/bytecode/tests/functions/verify_contract_bytecode_with_configurables.rs b/tests/src/bytecode/tests/functions/verify_contract_bytecode_with_configurables.rs index 3a41df2f..2c88b4d1 100644 --- a/tests/src/bytecode/tests/functions/verify_contract_bytecode_with_configurables.rs +++ b/tests/src/bytecode/tests/functions/verify_contract_bytecode_with_configurables.rs @@ -108,4 +108,27 @@ mod revert { ) .await; } + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + let my_configurables: Vec<(u64, Vec)> = Vec::new(); + + // Deploy the new simple contract with the bytecode that contains the changes + let (simple_contract_instance, id) = + deploy_simple_contract_with_configurables_from_file(wallet.clone(), 0).await; + + // Call the contract and compute the bytecode root + verify_simple_contract_bytecode_with_configurables( + &test_contract_instance, + empty_bytecode, + my_configurables, + id, + simple_contract_instance, + ) + .await; + } } diff --git a/tests/src/bytecode/tests/functions/verify_predicate_address.rs b/tests/src/bytecode/tests/functions/verify_predicate_address.rs index a2fae236..23b9ccea 100644 --- a/tests/src/bytecode/tests/functions/verify_predicate_address.rs +++ b/tests/src/bytecode/tests/functions/verify_predicate_address.rs @@ -51,4 +51,22 @@ mod revert { ) .await; } + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + + // Create an instance of the predicate + let predicate_instance = setup_predicate_from_file(wallet.clone()).await; + + verify_predicate_address( + &test_contract_instance, + empty_bytecode, + predicate_instance.address().into(), + ) + .await; + } } diff --git a/tests/src/bytecode/tests/functions/verify_predicate_address_with_configurables.rs b/tests/src/bytecode/tests/functions/verify_predicate_address_with_configurables.rs index a6f239ad..d8930d2d 100644 --- a/tests/src/bytecode/tests/functions/verify_predicate_address_with_configurables.rs +++ b/tests/src/bytecode/tests/functions/verify_predicate_address_with_configurables.rs @@ -64,4 +64,25 @@ mod revert { ) .await; } + + #[tokio::test] + #[should_panic] + async fn when_bytecode_is_empty() { + let (test_contract_instance, wallet) = test_contract_instance().await; + + let empty_bytecode: Vec = Vec::new(); + let my_configurables: Vec<(u64, Vec)> = Vec::new(); + + // Create an instance of the predicate + let predicate_instance = + setup_predicate_from_file_with_configurable(wallet.clone(), 0).await; + + verify_predicate_address_with_configurables( + &test_contract_instance, + empty_bytecode, + my_configurables, + predicate_instance.address().into(), + ) + .await; + } } diff --git a/tests/src/fixed_point/ifp128_div_test/src/main.sw b/tests/src/fixed_point/ifp128_div_test/src/main.sw deleted file mode 100644 index cd535388..00000000 --- a/tests/src/fixed_point/ifp128_div_test/src/main.sw +++ /dev/null @@ -1,24 +0,0 @@ -script; - -use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - -fn main() -> bool { - let zero = IFP128::from(UFP64::from_uint(0)); - let mut up = IFP128::from(UFP64::from_uint(1)); - let mut down = IFP128::from(UFP64::from_uint(2)); - let mut res = up / down; - assert(res == IFP128::from(UFP64::from(2147483648))); - - up = IFP128::from(UFP64::from_uint(4)); - down = IFP128::from(UFP64::from_uint(2)); - res = up / down; - assert(res == IFP128::from(UFP64::from_uint(2))); - - up = IFP128::from(UFP64::from_uint(9)); - down = IFP128::from(UFP64::from_uint(4)); - res = up / down; - - assert(res == IFP128::from(UFP64::from(9663676416))); - - true -} diff --git a/tests/src/fixed_point/ifp128_div_test/tests/mod.rs b/tests/src/fixed_point/ifp128_div_test/tests/mod.rs deleted file mode 100644 index a3911d22..00000000 --- a/tests/src/fixed_point/ifp128_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp128Div", - abi = "src/fixed_point/ifp128_div_test/out/release/ifp128_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp128_div_test_script() { - let path_to_bin = "src/fixed_point/ifp128_div_test/out/release/ifp128_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp128Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp128_test/mod.rs b/tests/src/fixed_point/ifp128_test/mod.rs deleted file mode 100644 index 14f00389..00000000 --- a/tests/src/fixed_point/ifp128_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ifp128_test/src/main.sw b/tests/src/fixed_point/ifp128_test/src/main.sw deleted file mode 100644 index 798b155a..00000000 --- a/tests/src/fixed_point/ifp128_test/src/main.sw +++ /dev/null @@ -1,69 +0,0 @@ -script; - -use sway_libs::fixed_point::{ifp128::IFP128, ufp64::UFP64}; - -fn main() -> bool { - // arithmetic - let one = IFP128::from(UFP64::from_uint(1)); - let two = IFP128::from(UFP64::from_uint(2)); - let mut res = two + one; - assert(IFP128::from(UFP64::from_uint(3)) == res); - - let ifp_128_10 = IFP128::from(UFP64::from_uint(10)); - res = ifp_128_10 + two; - assert(IFP128::from(UFP64::from_uint(12)) == res); - - let ifp_128_48 = IFP128::from(UFP64::from_uint(48)); - let six = IFP128::from(UFP64::from_uint(6)); - res = ifp_128_48 - six; - assert(IFP128::from(UFP64::from_uint(42)) == res); - - let ifp_128_169 = IFP128::from(UFP64::from_uint(169)); - let ifp_128_13 = IFP128::from(UFP64::from_uint(13)); - res = ifp_128_169 - ifp_128_13; - assert(IFP128::from(UFP64::from_uint(156)) == res); - - // recip - let mut value = IFP128::from(UFP64::from_uint(7)); - res = IFP128::recip(value); - assert(IFP128::from(UFP64::from(613566756)) == res); - - // trunc - value = IFP128::from(UFP64::from_uint(7)); - res = value.trunc(); - assert(IFP128::from(UFP64::from(30064771072)) == res); - - // floor - value = IFP128::from(UFP64::from_uint(1) + UFP64::from(3)); - res = value.floor(); - assert(IFP128::from_uint(1) == res); - - // fract - value = IFP128::from(UFP64::from_uint(1) + UFP64::from(3)); - res = value.fract(); - assert(IFP128::from(UFP64::from(3)) == res); - - value = IFP128::from_uint(1); - res = value.fract(); - assert(IFP128::from_uint(0) == res); - - // ceil - value = IFP128::from(UFP64::from_uint(1) + UFP64::from(3)); - res = value.ceil(); - assert(IFP128::from_uint(2) == res); - - value = IFP128::from_uint(1); - res = value.ceil(); - assert(IFP128::from_uint(1) == res); - - // round - value = IFP128::from(UFP64::from_uint(1) + UFP64::from(3)); - res = value.round(); - assert(IFP128::from_uint(1) == res); - - value = IFP128::from(UFP64::from_uint(1) + UFP64::from((1 << 32) + 1)); - res = value.round(); - assert(IFP128::from_uint(2) == res); - - true -} diff --git a/tests/src/fixed_point/ifp128_test/tests/mod.rs b/tests/src/fixed_point/ifp128_test/tests/mod.rs deleted file mode 100644 index 42093a08..00000000 --- a/tests/src/fixed_point/ifp128_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp128", - abi = "src/fixed_point/ifp128_test/out/release/ifp128_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp128_test_script() { - let path_to_bin = "src/fixed_point/ifp128_test/out/release/ifp128_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp128::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp256_div_test/mod.rs b/tests/src/fixed_point/ifp256_div_test/mod.rs deleted file mode 100644 index 14f00389..00000000 --- a/tests/src/fixed_point/ifp256_div_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ifp256_div_test/src/main.sw b/tests/src/fixed_point/ifp256_div_test/src/main.sw deleted file mode 100644 index 64b0947c..00000000 --- a/tests/src/fixed_point/ifp256_div_test/src/main.sw +++ /dev/null @@ -1,25 +0,0 @@ -script; - -use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128}; - -fn main() -> bool { - let zero = IFP256::from(UFP128::from((0, 0))); - let mut up = IFP256::from(UFP128::from((1, 0))); - let mut down = IFP256::from(UFP128::from((2, 0))); - let mut res = up / down; - assert(res == IFP256::from(UFP128::from((0, 9223372036854775808)))); - - up = IFP256::from(UFP128::from((4, 0))); - down = IFP256::from(UFP128::from((2, 0))); - res = up / down; - - assert(res == IFP256::from(UFP128::from((2, 0)))); - - up = IFP256::from(UFP128::from((9, 0))); - down = IFP256::from(UFP128::from((4, 0))); - res = up / down; - - assert(res == IFP256::from(UFP128::from((2, 4611686018427387904)))); - - true -} diff --git a/tests/src/fixed_point/ifp256_div_test/tests/mod.rs b/tests/src/fixed_point/ifp256_div_test/tests/mod.rs deleted file mode 100644 index 6b28d113..00000000 --- a/tests/src/fixed_point/ifp256_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp256Div", - abi = "src/fixed_point/ifp256_div_test/out/release/ifp256_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp256_div_test_script() { - let path_to_bin = "src/fixed_point/ifp256_div_test/out/release/ifp256_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp256Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp256_test/mod.rs b/tests/src/fixed_point/ifp256_test/mod.rs deleted file mode 100644 index 14f00389..00000000 --- a/tests/src/fixed_point/ifp256_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ifp256_test/src/main.sw b/tests/src/fixed_point/ifp256_test/src/main.sw deleted file mode 100644 index 88c8edcc..00000000 --- a/tests/src/fixed_point/ifp256_test/src/main.sw +++ /dev/null @@ -1,69 +0,0 @@ -script; - -use sway_libs::fixed_point::{ifp256::IFP256, ufp128::UFP128}; - -fn main() -> bool { - // arithmetic - let one = IFP256::from(UFP128::from((1, 0))); - let two = IFP256::from(UFP128::from((2, 0))); - let mut res = two + one; - assert(IFP256::from(UFP128::from((3, 0))) == res); - - let ifp_256_10 = IFP256::from(UFP128::from((10, 0))); - res = ifp_256_10 + two; - assert(IFP256::from(UFP128::from((12, 0))) == res); - - let ifp_256_48 = IFP256::from(UFP128::from((48, 0))); - let six = IFP256::from(UFP128::from((6, 0))); - res = ifp_256_48 - six; - assert(IFP256::from(UFP128::from((42, 0))) == res); - - let ifp_256_169 = IFP256::from(UFP128::from((169, 0))); - let ifp_256_13 = IFP256::from(UFP128::from((13, 0))); - res = ifp_256_169 - ifp_256_13; - assert(IFP256::from(UFP128::from((156, 0))) == res); - - // recip - let mut value = IFP256::from(UFP128::from((1, 3))); - res = IFP256::recip(value); - assert(IFP256::from(UFP128::from((0, 18446744073709551613))) == res); - - // trunc - let mut value = IFP256::from(UFP128::from((1, 3))); - res = value.trunc(); - assert(IFP256::from_uint(1) == res); - - // floor - value = IFP256::from(UFP128::from((1, 3))); - res = value.floor(); - assert(IFP256::from_uint(1) == res); - - // fract - value = IFP256::from(UFP128::from((1, 3))); - res = value.fract(); - assert(IFP256::from(UFP128::from((0, 3))) == res); - - value = IFP256::from_uint(1); - res = value.fract(); - assert(IFP256::from_uint(0) == res); - - // ceil - value = IFP256::from(UFP128::from((1, 3))); - res = value.ceil(); - assert(IFP256::from_uint(2) == res); - - value = IFP256::from_uint(1); - res = value.ceil(); - assert(IFP256::from_uint(1) == res); - - // round - value = IFP256::from(UFP128::from((1, 3))); - res = value.round(); - assert(IFP256::from_uint(1) == res); - - value = IFP256::from(UFP128::from((1, (1 << 63) + 1))); - res = value.round(); - assert(IFP256::from_uint(2) == res); - - true -} diff --git a/tests/src/fixed_point/ifp256_test/tests/mod.rs b/tests/src/fixed_point/ifp256_test/tests/mod.rs deleted file mode 100644 index 04ff9192..00000000 --- a/tests/src/fixed_point/ifp256_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp256", - abi = "src/fixed_point/ifp256_test/out/release/ifp256_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp256_test_script() { - let path_to_bin = "src/fixed_point/ifp256_test/out/release/ifp256_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp256::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_div_test/Forc.toml b/tests/src/fixed_point/ifp64_div_test/Forc.toml deleted file mode 100644 index b10e1576..00000000 --- a/tests/src/fixed_point/ifp64_div_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ifp64_div_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_div_test/src/main.sw b/tests/src/fixed_point/ifp64_div_test/src/main.sw deleted file mode 100644 index 6b46288d..00000000 --- a/tests/src/fixed_point/ifp64_div_test/src/main.sw +++ /dev/null @@ -1,32 +0,0 @@ -script; - -use sway_libs::fixed_point::ifp64::IFP64; -use std::assert::assert; - -fn main() -> bool { - let one = IFP64::from_uint(1u32); - let two = IFP64::from_uint(2u32); - let mut res = two / one; - assert(two == res); - - let ufp_64_10 = IFP64::from_uint(10u32); - res = ufp_64_10 / two; - assert(IFP64::from_uint(5u32) == res); - - let ufp_64_48 = IFP64::from_uint(48u32); - let six = IFP64::from_uint(6u32); - res = ufp_64_48 / six; - assert(IFP64::from_uint(8u32) == res); - - let ufp_64_169 = IFP64::from_uint(169u32); - let ufp_64_13 = IFP64::from_uint(13u32); - res = ufp_64_169 / ufp_64_13; - assert(IFP64::from_uint(13u32) == res); - - let ufp_64_35 = IFP64::from_uint(35u32); - let ufp_64_5 = IFP64::from_uint(5u32); - res = ufp_64_35 / ufp_64_5; - assert(IFP64::from_uint(7u32) == res); - - true -} diff --git a/tests/src/fixed_point/ifp64_div_test/tests/mod.rs b/tests/src/fixed_point/ifp64_div_test/tests/mod.rs deleted file mode 100644 index 0e0c41d8..00000000 --- a/tests/src/fixed_point/ifp64_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp64Div", - abi = "src/fixed_point/ifp64_div_test/out/release/ifp64_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp64_div_test_script() { - let path_to_bin = "src/fixed_point/ifp64_div_test/out/release/ifp64_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp64Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_exp_test/Forc.toml b/tests/src/fixed_point/ifp64_exp_test/Forc.toml deleted file mode 100644 index 975e3e45..00000000 --- a/tests/src/fixed_point/ifp64_exp_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ifp64_exp_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_exp_test/src/main.sw b/tests/src/fixed_point/ifp64_exp_test/src/main.sw deleted file mode 100644 index a45bdd95..00000000 --- a/tests/src/fixed_point/ifp64_exp_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ifp64::IFP64; -use std::assert::assert; - -fn main() -> bool { - let one = IFP64::from_uint(1u32); - let mut res = IFP64::exp(one); - assert(res.underlying().underlying() == 178142u32); - - let two = IFP64::from_uint(2u32); - res = IFP64::exp(two); - assert(res.underlying().underlying() == 483696u32); - - let four = IFP64::from_uint(4u32); - res = IFP64::exp(four); - assert(res.underlying().underlying() == 3394688u32); - - let seven = IFP64::from_uint(7u32); - res = IFP64::exp(seven); - assert(res.underlying().underlying() == 43019636u32); - - let ten = IFP64::from_uint(10u32); - res = IFP64::exp(ten); - assert(res.underlying().underlying() == 317819696u32); - - true -} diff --git a/tests/src/fixed_point/ifp64_exp_test/tests/mod.rs b/tests/src/fixed_point/ifp64_exp_test/tests/mod.rs deleted file mode 100644 index 05e749f2..00000000 --- a/tests/src/fixed_point/ifp64_exp_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp64Exp", - abi = "src/fixed_point/ifp64_exp_test/out/release/ifp64_exp_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp64_exp_test_script() { - let path_to_bin = "src/fixed_point/ifp64_exp_test/out/release/ifp64_exp_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp64Exp::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_mul_test/.gitignore b/tests/src/fixed_point/ifp64_mul_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ifp64_mul_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ifp64_mul_test/Forc.toml b/tests/src/fixed_point/ifp64_mul_test/Forc.toml deleted file mode 100644 index 33d65845..00000000 --- a/tests/src/fixed_point/ifp64_mul_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ifp64_mul_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_mul_test/src/main.sw b/tests/src/fixed_point/ifp64_mul_test/src/main.sw deleted file mode 100644 index 1bbebf27..00000000 --- a/tests/src/fixed_point/ifp64_mul_test/src/main.sw +++ /dev/null @@ -1,33 +0,0 @@ -script; - -use sway_libs::fixed_point::ifp64::IFP64; -use std::assert::assert; - -fn main() -> bool { - let one = IFP64::from_uint(1u32); - let two = IFP64::from_uint(2u32); - let mut res = one * two; - assert(two == res); - - let ufp_64_10 = IFP64::from_uint(10u32); - let ufp_64_20 = IFP64::from_uint(4u32); - res = ufp_64_10 * ufp_64_20; - assert(IFP64::from_uint(40u32) == res); - - let ufp_64_11 = IFP64::from_uint(11u32); - let ufp_64_12 = IFP64::from_uint(12u32); - res = ufp_64_11 * ufp_64_12; - assert(IFP64::from_uint(132u32) == res); - - let ufp_64_150 = IFP64::from_uint(150u32); - let ufp_64_8 = IFP64::from_uint(8u32); - res = ufp_64_150 * ufp_64_8; - assert(IFP64::from_uint(1200u32) == res); - - let ufp_64_7 = IFP64::from_uint(7u32); - let ufp_64_5 = IFP64::from_uint(5u32); - res = ufp_64_7 * ufp_64_5; - assert(IFP64::from_uint(35u32) == res); - - true -} diff --git a/tests/src/fixed_point/ifp64_mul_test/tests/mod.rs b/tests/src/fixed_point/ifp64_mul_test/tests/mod.rs deleted file mode 100644 index 25194a39..00000000 --- a/tests/src/fixed_point/ifp64_mul_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp64Mul", - abi = "src/fixed_point/ifp64_mul_test/out/release/ifp64_mul_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp64_mul_test_script() { - let path_to_bin = "src/fixed_point/ifp64_mul_test/out/release/ifp64_mul_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp64Mul::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_pow_test/.gitignore b/tests/src/fixed_point/ifp64_pow_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ifp64_pow_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ifp64_pow_test/Forc.toml b/tests/src/fixed_point/ifp64_pow_test/Forc.toml deleted file mode 100644 index 7a2f0351..00000000 --- a/tests/src/fixed_point/ifp64_pow_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ifp64_pow_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_pow_test/src/main.sw b/tests/src/fixed_point/ifp64_pow_test/src/main.sw deleted file mode 100644 index 2dc5e038..00000000 --- a/tests/src/fixed_point/ifp64_pow_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ifp64::IFP64; -use std::assert::assert; - -fn main() -> bool { - let one = IFP64::from_uint(1u32); - let mut res = one.pow(1u32); - assert(one == res); - - let two = IFP64::from_uint(2u32); - res = two.pow(3u32); - assert(IFP64::from_uint(8u32) == res); - - let ufp_64_11 = IFP64::from_uint(11u32); - res = ufp_64_11.pow(2u32); - assert(IFP64::from_uint(121u32) == res); - - let five = IFP64::from_uint(5u32); - res = five.pow(3u32); - assert(IFP64::from_uint(125u32) == res); - - let seven = IFP64::from_uint(7u32); - res = seven.pow(2u32); - assert(IFP64::from_uint(49u32) == res); - - true -} diff --git a/tests/src/fixed_point/ifp64_pow_test/tests/mod.rs b/tests/src/fixed_point/ifp64_pow_test/tests/mod.rs deleted file mode 100644 index 5850d02b..00000000 --- a/tests/src/fixed_point/ifp64_pow_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp64Pow", - abi = "src/fixed_point/ifp64_pow_test/out/release/ifp64_pow_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp64_pow_test_script() { - let path_to_bin = "src/fixed_point/ifp64_pow_test/out/release/ifp64_pow_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp64Pow::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_test/.gitignore b/tests/src/fixed_point/ifp64_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ifp64_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ifp64_test/Forc.toml b/tests/src/fixed_point/ifp64_test/Forc.toml deleted file mode 100644 index b73e1bd4..00000000 --- a/tests/src/fixed_point/ifp64_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ifp64_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_test/src/main.sw b/tests/src/fixed_point/ifp64_test/src/main.sw deleted file mode 100644 index 48a85d3e..00000000 --- a/tests/src/fixed_point/ifp64_test/src/main.sw +++ /dev/null @@ -1,84 +0,0 @@ -script; - -use sway_libs::fixed_point::{ifp64::IFP64, ufp32::UFP32}; -use std::assert::assert; - -fn main() -> bool { - // arithmetic - let one = IFP64::from_uint(1u32); - let two = IFP64::from_uint(2u32); - let mut res = two + one; - assert(IFP64::from_uint(3u32) == res); - - let ifp_64_10 = IFP64::from_uint(10u32); - res = ifp_64_10 + two; - assert(IFP64::from_uint(12u32) == res); - - let ufp_64_48 = IFP64::from_uint(48u32); - let six = IFP64::from_uint(6u32); - res = ufp_64_48 - six; - assert(IFP64::from_uint(42u32) == res); - - let ufp_64_169 = IFP64::from_uint(169u32); - let ufp_64_13 = IFP64::from_uint(13u32); - res = ufp_64_169 - ufp_64_13; - assert(IFP64::from_uint(156u32) == res); - - // recip - let mut u_value = UFP32::from(1u32 << 16 + 3); - let mut value = IFP64::from(u_value); - - res = IFP64::recip(value); - assert(IFP64::from(UFP32::from(8192u32)) == res); - - // trunc - u_value = UFP32::from((1u32 << 16) + 3u32); - value = IFP64::from(u_value); - - res = value.trunc(); - assert(IFP64::from_uint(1u32) == res); - - // floor - u_value = UFP32::from((1u32 << 16) + 3u32); - value = IFP64::from(u_value); - - res = value.floor(); - assert(IFP64::from_uint(1u32) == res); - - // fract - u_value = UFP32::from((1u32 << 16) + 3u32); - value = IFP64::from(u_value); - - res = value.fract(); - assert(IFP64::from(UFP32::from(3u32)) == res); - - value = IFP64::from_uint(1u32); - res = value.fract(); - assert(IFP64::from_uint(0u32) == res); - - // ceil - u_value = UFP32::from((1u32 << 16) + 3u32); - value = IFP64::from(u_value); - - res = value.ceil(); - assert(IFP64::from_uint(2u32) == res); - - value = IFP64::from_uint(1u32); - res = value.ceil(); - assert(IFP64::from_uint(1u32) == res); - - // round - u_value = UFP32::from((1u32 << 16) + 3u32); - value = IFP64::from(u_value); - - res = value.round(); - assert(IFP64::from_uint(1u32) == res); - - u_value = UFP32::from((1u32 << 16) + (1u32 << 15) + 1u32); - value = IFP64::from(u_value); - - res = value.round(); - assert(IFP64::from_uint(2u32) == res); - - true -} diff --git a/tests/src/fixed_point/ifp64_test/tests/mod.rs b/tests/src/fixed_point/ifp64_test/tests/mod.rs deleted file mode 100644 index 74fa67de..00000000 --- a/tests/src/fixed_point/ifp64_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestIfp64", - abi = "src/fixed_point/ifp64_test/out/release/ifp64_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ifp64_test_script() { - let path_to_bin = "src/fixed_point/ifp64_test/out/release/ifp64_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestIfp64::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/mod.rs b/tests/src/fixed_point/mod.rs deleted file mode 100644 index 9c7bb6fb..00000000 --- a/tests/src/fixed_point/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -mod ifp128_div_test; -mod ifp128_test; -mod ifp256_div_test; -mod ifp256_test; -mod ifp64_div_test; -mod ifp64_exp_test; -mod ifp64_mul_test; -mod ifp64_pow_test; -mod ifp64_test; -mod ufp128_div_test; -mod ufp128_test; -mod ufp32_div_test; -mod ufp32_exp_test; -mod ufp32_mul_test; -mod ufp32_pow_test; -mod ufp32_root_test; -mod ufp32_test; -mod ufp64_div_test; -mod ufp64_exp_test; -mod ufp64_mul_test; -mod ufp64_pow_test; -mod ufp64_root_test; -mod ufp64_test; diff --git a/tests/src/fixed_point/ufp128_div_test/.gitignore b/tests/src/fixed_point/ufp128_div_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp128_div_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp128_div_test/Forc.toml b/tests/src/fixed_point/ufp128_div_test/Forc.toml deleted file mode 100644 index 33856bae..00000000 --- a/tests/src/fixed_point/ufp128_div_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp128_div_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp128_div_test/mod.rs b/tests/src/fixed_point/ufp128_div_test/mod.rs deleted file mode 100644 index 14f00389..00000000 --- a/tests/src/fixed_point/ufp128_div_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp128_div_test/src/main.sw b/tests/src/fixed_point/ufp128_div_test/src/main.sw deleted file mode 100644 index fb179ad2..00000000 --- a/tests/src/fixed_point/ufp128_div_test/src/main.sw +++ /dev/null @@ -1,25 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp128::UFP128; - -fn main() -> bool { - let zero = UFP128::from((0, 0)); - let mut up = UFP128::from((1, 0)); - let mut down = UFP128::from((2, 0)); - let mut res = up / down; - assert(res == UFP128::from((0, 9223372036854775808))); - - up = UFP128::from((4, 0)); - down = UFP128::from((2, 0)); - res = up / down; - - assert(res == UFP128::from((2, 0))); - - up = UFP128::from((9, 0)); - down = UFP128::from((4, 0)); - res = up / down; - - assert(res == UFP128::from((2, 4611686018427387904))); - - true -} diff --git a/tests/src/fixed_point/ufp128_div_test/tests/mod.rs b/tests/src/fixed_point/ufp128_div_test/tests/mod.rs deleted file mode 100644 index aa195110..00000000 --- a/tests/src/fixed_point/ufp128_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp128Div", - abi = "src/fixed_point/ufp128_div_test/out/release/ufp128_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp128_div_test_script() { - let path_to_bin = "src/fixed_point/ufp128_div_test/out/release/ufp128_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp128Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp128_test/.gitignore b/tests/src/fixed_point/ufp128_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp128_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp128_test/Forc.toml b/tests/src/fixed_point/ufp128_test/Forc.toml deleted file mode 100644 index ad1ecd32..00000000 --- a/tests/src/fixed_point/ufp128_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp128_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp128_test/mod.rs b/tests/src/fixed_point/ufp128_test/mod.rs deleted file mode 100644 index 14f00389..00000000 --- a/tests/src/fixed_point/ufp128_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp128_test/src/main.sw b/tests/src/fixed_point/ufp128_test/src/main.sw deleted file mode 100644 index e135160d..00000000 --- a/tests/src/fixed_point/ufp128_test/src/main.sw +++ /dev/null @@ -1,70 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp128::UFP128; -use std::u128::U128; - -fn main() -> bool { - // arithmetic - let one = UFP128::from((1, 0)); - let two = UFP128::from((2, 0)); - let mut res = two + one; - assert(UFP128::from((3, 0)) == res); - - let ufp_128_10 = UFP128::from((10, 0)); - res = ufp_128_10 + two; - assert(UFP128::from((12, 0)) == res); - - let ufp_128_48 = UFP128::from((48, 0)); - let six = UFP128::from((6, 0)); - res = ufp_128_48 - six; - assert(UFP128::from((42, 0)) == res); - - let ufp_128_169 = UFP128::from((169, 0)); - let ufp_128_13 = UFP128::from((13, 0)); - res = ufp_128_169 - ufp_128_13; - assert(UFP128::from((156, 0)) == res); - - // recip - let mut value = UFP128::from(U128::from((1, 3))); - res = UFP128::recip(value); - assert(UFP128::from(U128::from((0, 18446744073709551613))) == res); - - // trunc - let mut value = UFP128::from(U128::from((1, 3))); - res = value.trunc(); - assert(UFP128::from_uint(1) == res); - - // floor - value = UFP128::from(U128::from((1, 3))); - res = value.floor(); - assert(UFP128::from_uint(1) == res); - - // fract - value = UFP128::from(U128::from((1, 3))); - res = value.fract(); - assert(UFP128::from(U128::from((0, 3))) == res); - - value = UFP128::from_uint(1); - res = value.fract(); - assert(UFP128::from_uint(0) == res); - - // ceil - value = UFP128::from(U128::from((1, 3))); - res = value.ceil(); - assert(UFP128::from_uint(2) == res); - - value = UFP128::from_uint(1); - res = value.ceil(); - assert(UFP128::from_uint(1) == res); - - // round - value = UFP128::from(U128::from((1, 3))); - res = value.round(); - assert(UFP128::from_uint(1) == res); - - value = UFP128::from(U128::from((1, (1 << 63) + 1))); - res = value.round(); - assert(UFP128::from_uint(2) == res); - - true -} diff --git a/tests/src/fixed_point/ufp128_test/tests/mod.rs b/tests/src/fixed_point/ufp128_test/tests/mod.rs deleted file mode 100644 index a26fe8de..00000000 --- a/tests/src/fixed_point/ufp128_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp128", - abi = "src/fixed_point/ufp128_test/out/release/ufp128_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp128_test_script() { - let path_to_bin = "src/fixed_point/ufp128_test/out/release/ufp128_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp128::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_div_test/.gitignore b/tests/src/fixed_point/ufp32_div_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_div_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_div_test/Forc.toml b/tests/src/fixed_point/ufp32_div_test/Forc.toml deleted file mode 100644 index 687bbe67..00000000 --- a/tests/src/fixed_point/ufp32_div_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_div_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_div_test/src/main.sw b/tests/src/fixed_point/ufp32_div_test/src/main.sw deleted file mode 100644 index 4eb03b99..00000000 --- a/tests/src/fixed_point/ufp32_div_test/src/main.sw +++ /dev/null @@ -1,32 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - let one = UFP32::from_uint(1); - let two = UFP32::from_uint(2); - let mut res = two / one; - assert(two == res); - - let ufp_64_10 = UFP32::from_uint(10); - res = ufp_64_10 / two; - assert(UFP32::from_uint(5) == res); - - let ufp_64_48 = UFP32::from_uint(48); - let six = UFP32::from_uint(6); - res = ufp_64_48 / six; - assert(UFP32::from_uint(8) == res); - - let ufp_64_169 = UFP32::from_uint(169); - let ufp_64_13 = UFP32::from_uint(13); - res = ufp_64_169 / ufp_64_13; - assert(UFP32::from_uint(13) == res); - - let ufp_64_35 = UFP32::from_uint(35); - let ufp_64_5 = UFP32::from_uint(5); - res = ufp_64_35 / ufp_64_5; - assert(UFP32::from_uint(7) == res); - - true -} diff --git a/tests/src/fixed_point/ufp32_div_test/tests/mod.rs b/tests/src/fixed_point/ufp32_div_test/tests/mod.rs deleted file mode 100644 index 250302fd..00000000 --- a/tests/src/fixed_point/ufp32_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32Div", - abi = "src/fixed_point/ufp32_div_test/out/release/ufp32_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_div_test_script() { - let path_to_bin = "src/fixed_point/ufp32_div_test/out/release/ufp32_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_exp_test/.gitignore b/tests/src/fixed_point/ufp32_exp_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_exp_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_exp_test/Forc.toml b/tests/src/fixed_point/ufp32_exp_test/Forc.toml deleted file mode 100644 index a5f46a99..00000000 --- a/tests/src/fixed_point/ufp32_exp_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_exp_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_exp_test/mod.rs b/tests/src/fixed_point/ufp32_exp_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp32_exp_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp32_exp_test/src/main.sw b/tests/src/fixed_point/ufp32_exp_test/src/main.sw deleted file mode 100644 index 56a6533d..00000000 --- a/tests/src/fixed_point/ufp32_exp_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - let one = UFP32::from_uint(1); - let mut res = UFP32::exp(one); - assert(res.underlying() == 11674811894); - - let two = UFP32::from_uint(2); - res = UFP32::exp(two); - assert(res.underlying() == 31700949040); - - let four = UFP32::from_uint(4); - res = UFP32::exp(four); - assert(res.underlying() == 222506572928); - - let seven = UFP32::from_uint(7); - res = UFP32::exp(seven); - assert(res.underlying() == 2819944203710); - - let ten = UFP32::from_uint(10); - res = UFP32::exp(ten); - assert(res.underlying() == 20833521987056); - - true -} diff --git a/tests/src/fixed_point/ufp32_exp_test/tests/mod.rs b/tests/src/fixed_point/ufp32_exp_test/tests/mod.rs deleted file mode 100644 index df10cd35..00000000 --- a/tests/src/fixed_point/ufp32_exp_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32Exp", - abi = "src/fixed_point/ufp32_exp_test/out/release/ufp32_exp_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_exp_test_script() { - let path_to_bin = "src/fixed_point/ufp32_exp_test/out/release/ufp32_exp_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32Exp::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_mul_test/.gitignore b/tests/src/fixed_point/ufp32_mul_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_mul_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_mul_test/Forc.toml b/tests/src/fixed_point/ufp32_mul_test/Forc.toml deleted file mode 100644 index a111aa10..00000000 --- a/tests/src/fixed_point/ufp32_mul_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_mul_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_mul_test/mod.rs b/tests/src/fixed_point/ufp32_mul_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp32_mul_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp32_mul_test/src/main.sw b/tests/src/fixed_point/ufp32_mul_test/src/main.sw deleted file mode 100644 index cf8ba8cd..00000000 --- a/tests/src/fixed_point/ufp32_mul_test/src/main.sw +++ /dev/null @@ -1,33 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - let one = UFP32::from_uint(1); - let two = UFP32::from_uint(2); - let mut res = one * two; - assert(two == res); - - let ufp_64_10 = UFP32::from_uint(10); - let ufp_64_20 = UFP32::from_uint(4); - res = ufp_64_10 * ufp_64_20; - assert(UFP32::from_uint(40) == res); - - let ufp_64_11 = UFP32::from_uint(11); - let ufp_64_12 = UFP32::from_uint(12); - res = ufp_64_11 * ufp_64_12; - assert(UFP32::from_uint(132) == res); - - let ufp_64_150 = UFP32::from_uint(150); - let ufp_64_8 = UFP32::from_uint(8); - res = ufp_64_150 * ufp_64_8; - assert(UFP32::from_uint(1200) == res); - - let ufp_64_7 = UFP32::from_uint(7); - let ufp_64_5 = UFP32::from_uint(5); - res = ufp_64_7 * ufp_64_5; - assert(UFP32::from_uint(35) == res); - - true -} diff --git a/tests/src/fixed_point/ufp32_mul_test/tests/mod.rs b/tests/src/fixed_point/ufp32_mul_test/tests/mod.rs deleted file mode 100644 index f5872c77..00000000 --- a/tests/src/fixed_point/ufp32_mul_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32Mul", - abi = "src/fixed_point/ufp32_mul_test/out/release/ufp32_mul_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_mul_test_script() { - let path_to_bin = "src/fixed_point/ufp32_mul_test/out/release/ufp32_mul_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32Mul::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_pow_test/.gitignore b/tests/src/fixed_point/ufp32_pow_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_pow_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_pow_test/Forc.toml b/tests/src/fixed_point/ufp32_pow_test/Forc.toml deleted file mode 100644 index 34d68507..00000000 --- a/tests/src/fixed_point/ufp32_pow_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_pow_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_pow_test/mod.rs b/tests/src/fixed_point/ufp32_pow_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp32_pow_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp32_pow_test/src/main.sw b/tests/src/fixed_point/ufp32_pow_test/src/main.sw deleted file mode 100644 index 9369d55e..00000000 --- a/tests/src/fixed_point/ufp32_pow_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - let one = UFP32::from_uint(1); - let mut res = one.pow(1u32); - assert(one == res); - - let two = UFP32::from_uint(2); - res = two.pow(3u32); - assert(UFP32::from_uint(8) == res); - - let ufp_64_11 = UFP32::from_uint(11); - res = ufp_64_11.pow(2u32); - assert(UFP32::from_uint(121) == res); - - let five = UFP32::from_uint(5); - res = five.pow(3u32); - assert(UFP32::from_uint(125) == res); - - let seven = UFP32::from_uint(7); - res = seven.pow(2u32); - assert(UFP32::from_uint(49) == res); - - true -} diff --git a/tests/src/fixed_point/ufp32_pow_test/tests/mod.rs b/tests/src/fixed_point/ufp32_pow_test/tests/mod.rs deleted file mode 100644 index f3c41a94..00000000 --- a/tests/src/fixed_point/ufp32_pow_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32Pow", - abi = "src/fixed_point/ufp32_pow_test/out/release/ufp32_pow_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_pow_test_script() { - let path_to_bin = "src/fixed_point/ufp32_pow_test/out/release/ufp32_pow_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32Pow::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_root_test/.gitignore b/tests/src/fixed_point/ufp32_root_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_root_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_root_test/Forc.toml b/tests/src/fixed_point/ufp32_root_test/Forc.toml deleted file mode 100644 index 0e95d661..00000000 --- a/tests/src/fixed_point/ufp32_root_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_root_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_root_test/mod.rs b/tests/src/fixed_point/ufp32_root_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp32_root_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp32_root_test/src/main.sw b/tests/src/fixed_point/ufp32_root_test/src/main.sw deleted file mode 100644 index cb3f87a8..00000000 --- a/tests/src/fixed_point/ufp32_root_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - let one = UFP32::from_uint(1); - let mut res = UFP32::sqrt(one); - assert(one == res); - - let ufp32_100 = UFP32::from_uint(100); - res = UFP32::sqrt(ufp32_100); - assert(UFP32::from_uint(10) == res); - - let ufp32_121 = UFP32::from_uint(121); - res = UFP32::sqrt(ufp32_121); - assert(UFP32::from_uint(11) == res); - - let ufp32_169 = UFP32::from_uint(169); - res = UFP32::sqrt(ufp32_169); - assert(UFP32::from_uint(13) == res); - - let ufp32_49 = UFP32::from_uint(49); - res = UFP32::sqrt(ufp32_49); - assert(UFP32::from_uint(7) == res); - - true -} diff --git a/tests/src/fixed_point/ufp32_root_test/tests/mod.rs b/tests/src/fixed_point/ufp32_root_test/tests/mod.rs deleted file mode 100644 index bad3073e..00000000 --- a/tests/src/fixed_point/ufp32_root_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32Root", - abi = "src/fixed_point/ufp32_root_test/out/release/ufp32_root_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_root_test_script() { - let path_to_bin = "src/fixed_point/ufp32_root_test/out/release/ufp32_root_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32Root::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp32_test/.gitignore b/tests/src/fixed_point/ufp32_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp32_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp32_test/Forc.toml b/tests/src/fixed_point/ufp32_test/Forc.toml deleted file mode 100644 index 0e3a2fdd..00000000 --- a/tests/src/fixed_point/ufp32_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp32_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_test/mod.rs b/tests/src/fixed_point/ufp32_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp32_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp32_test/src/main.sw b/tests/src/fixed_point/ufp32_test/src/main.sw deleted file mode 100644 index 4c6d3cf2..00000000 --- a/tests/src/fixed_point/ufp32_test/src/main.sw +++ /dev/null @@ -1,70 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp32::UFP32; -use std::assert::assert; - -fn main() -> bool { - // arithmetic - let one = UFP32::from_uint(1); - let two = UFP32::from_uint(2); - let mut res = two + one; - assert(UFP32::from_uint(3) == res); - - let ufp_32_10 = UFP32::from_uint(10); - res = ufp_32_10 + two; - assert(UFP32::from_uint(12) == res); - - let ufp_32_48 = UFP32::from_uint(48); - let six = UFP32::from_uint(6); - res = ufp_32_48 - six; - assert(UFP32::from_uint(42) == res); - - let ufp_32_169 = UFP32::from_uint(169); - let ufp_32_13 = UFP32::from_uint(13); - res = ufp_32_169 - ufp_32_13; - assert(UFP32::from_uint(156) == res); - - // recip - let mut value = UFP32::from(3u32); - res = UFP32::recip(value); - assert(UFP32::from(536870912) == res); - - // trunc - value = UFP32::from(3u32); - res = value.trunc(); - assert(UFP32::from_uint(1) == res); - - // floor - value = UFP32::from(3u32); - res = value.floor(); - assert(UFP32::from_uint(1) == res); - - // fract - value = UFP32::from(3u32); - res = value.fract(); - assert(UFP32::from(3) == res); - - value = UFP32::from_uint(1); - res = value.fract(); - assert(UFP32::from_uint(0) == res); - - // ceil - value = UFP32::from(3u32); - res = value.ceil(); - assert(UFP32::from_uint(2) == res); - - value = UFP32::from_uint(1); - res = value.ceil(); - assert(UFP32::from_uint(1) == res); - - // round - value = UFP32::from(3u32); - res = value.round(); - assert(UFP32::from_uint(1) == res); - - value = UFP32::from(2147483649u32); - res = value.round(); - assert(UFP32::from_uint(2) == res); - - true -} diff --git a/tests/src/fixed_point/ufp32_test/tests/mod.rs b/tests/src/fixed_point/ufp32_test/tests/mod.rs deleted file mode 100644 index 732647c1..00000000 --- a/tests/src/fixed_point/ufp32_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp32", - abi = "src/fixed_point/ufp32_test/out/release/ufp32_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp32_test_script() { - let path_to_bin = "src/fixed_point/ufp32_test/out/release/ufp32_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp32::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_div_test/.gitignore b/tests/src/fixed_point/ufp64_div_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_div_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_div_test/Forc.toml b/tests/src/fixed_point/ufp64_div_test/Forc.toml deleted file mode 100644 index cc199bab..00000000 --- a/tests/src/fixed_point/ufp64_div_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_div_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_div_test/mod.rs b/tests/src/fixed_point/ufp64_div_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_div_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_div_test/src/main.sw b/tests/src/fixed_point/ufp64_div_test/src/main.sw deleted file mode 100644 index 7c9d4d27..00000000 --- a/tests/src/fixed_point/ufp64_div_test/src/main.sw +++ /dev/null @@ -1,32 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - let one = UFP64::from_uint(1); - let two = UFP64::from_uint(2); - let mut res = two / one; - assert(two == res); - - let ufp_64_10 = UFP64::from_uint(10); - res = ufp_64_10 / two; - assert(UFP64::from_uint(5) == res); - - let ufp_64_48 = UFP64::from_uint(48); - let six = UFP64::from_uint(6); - res = ufp_64_48 / six; - assert(UFP64::from_uint(8) == res); - - let ufp_64_169 = UFP64::from_uint(169); - let ufp_64_13 = UFP64::from_uint(13); - res = ufp_64_169 / ufp_64_13; - assert(UFP64::from_uint(13) == res); - - let ufp_64_35 = UFP64::from_uint(35); - let ufp_64_5 = UFP64::from_uint(5); - res = ufp_64_35 / ufp_64_5; - assert(UFP64::from_uint(7) == res); - - true -} diff --git a/tests/src/fixed_point/ufp64_div_test/tests/mod.rs b/tests/src/fixed_point/ufp64_div_test/tests/mod.rs deleted file mode 100644 index 48bfff19..00000000 --- a/tests/src/fixed_point/ufp64_div_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64Div", - abi = "src/fixed_point/ufp64_div_test/out/release/ufp64_div_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_div_test_script() { - let path_to_bin = "src/fixed_point/ufp64_div_test/out/release/ufp64_div_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64Div::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_exp_test/.gitignore b/tests/src/fixed_point/ufp64_exp_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_exp_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_exp_test/Forc.toml b/tests/src/fixed_point/ufp64_exp_test/Forc.toml deleted file mode 100644 index 7c087ce8..00000000 --- a/tests/src/fixed_point/ufp64_exp_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_exp_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_exp_test/mod.rs b/tests/src/fixed_point/ufp64_exp_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_exp_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_exp_test/src/main.sw b/tests/src/fixed_point/ufp64_exp_test/src/main.sw deleted file mode 100644 index 62936f00..00000000 --- a/tests/src/fixed_point/ufp64_exp_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - let one = UFP64::from_uint(1); - let mut res = UFP64::exp(one); - assert(res.underlying() == 11674811894); - - let two = UFP64::from_uint(2); - res = UFP64::exp(two); - assert(res.underlying() == 31700949040); - - let four = UFP64::from_uint(4); - res = UFP64::exp(four); - assert(res.underlying() == 222506572928); - - let seven = UFP64::from_uint(7); - res = UFP64::exp(seven); - assert(res.underlying() == 2819944203710); - - let ten = UFP64::from_uint(10); - res = UFP64::exp(ten); - assert(res.underlying() == 20833521987056); - - true -} diff --git a/tests/src/fixed_point/ufp64_exp_test/tests/mod.rs b/tests/src/fixed_point/ufp64_exp_test/tests/mod.rs deleted file mode 100644 index d25b952c..00000000 --- a/tests/src/fixed_point/ufp64_exp_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64Exp", - abi = "src/fixed_point/ufp64_exp_test/out/release/ufp64_exp_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_exp_test_script() { - let path_to_bin = "src/fixed_point/ufp64_exp_test/out/release/ufp64_exp_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64Exp::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_mul_test/.gitignore b/tests/src/fixed_point/ufp64_mul_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_mul_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_mul_test/Forc.toml b/tests/src/fixed_point/ufp64_mul_test/Forc.toml deleted file mode 100644 index feb01298..00000000 --- a/tests/src/fixed_point/ufp64_mul_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_mul_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_mul_test/mod.rs b/tests/src/fixed_point/ufp64_mul_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_mul_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_mul_test/src/main.sw b/tests/src/fixed_point/ufp64_mul_test/src/main.sw deleted file mode 100644 index 391cc3c6..00000000 --- a/tests/src/fixed_point/ufp64_mul_test/src/main.sw +++ /dev/null @@ -1,33 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - let one = UFP64::from_uint(1); - let two = UFP64::from_uint(2); - let mut res = one * two; - assert(two == res); - - let ufp_64_10 = UFP64::from_uint(10); - let ufp_64_20 = UFP64::from_uint(4); - res = ufp_64_10 * ufp_64_20; - assert(UFP64::from_uint(40) == res); - - let ufp_64_11 = UFP64::from_uint(11); - let ufp_64_12 = UFP64::from_uint(12); - res = ufp_64_11 * ufp_64_12; - assert(UFP64::from_uint(132) == res); - - let ufp_64_150 = UFP64::from_uint(150); - let ufp_64_8 = UFP64::from_uint(8); - res = ufp_64_150 * ufp_64_8; - assert(UFP64::from_uint(1200) == res); - - let ufp_64_7 = UFP64::from_uint(7); - let ufp_64_5 = UFP64::from_uint(5); - res = ufp_64_7 * ufp_64_5; - assert(UFP64::from_uint(35) == res); - - true -} diff --git a/tests/src/fixed_point/ufp64_mul_test/tests/mod.rs b/tests/src/fixed_point/ufp64_mul_test/tests/mod.rs deleted file mode 100644 index 8f386670..00000000 --- a/tests/src/fixed_point/ufp64_mul_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64Mul", - abi = "src/fixed_point/ufp64_mul_test/out/release/ufp64_mul_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_mul_test_script() { - let path_to_bin = "src/fixed_point/ufp64_mul_test/out/release/ufp64_mul_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64Mul::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_pow_test/.gitignore b/tests/src/fixed_point/ufp64_pow_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_pow_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_pow_test/Forc.toml b/tests/src/fixed_point/ufp64_pow_test/Forc.toml deleted file mode 100644 index ff7a780c..00000000 --- a/tests/src/fixed_point/ufp64_pow_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_pow_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_pow_test/mod.rs b/tests/src/fixed_point/ufp64_pow_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_pow_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_pow_test/src/main.sw b/tests/src/fixed_point/ufp64_pow_test/src/main.sw deleted file mode 100644 index 99199dd6..00000000 --- a/tests/src/fixed_point/ufp64_pow_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - let one = UFP64::from_uint(1); - let mut res = one.pow(1u32); - assert(one == res); - - let two = UFP64::from_uint(2); - res = two.pow(3u32); - assert(UFP64::from_uint(8) == res); - - let ufp_64_11 = UFP64::from_uint(11); - res = ufp_64_11.pow(2u32); - assert(UFP64::from_uint(121) == res); - - let five = UFP64::from_uint(5); - res = five.pow(3u32); - assert(UFP64::from_uint(125) == res); - - let seven = UFP64::from_uint(7); - res = seven.pow(2u32); - assert(UFP64::from_uint(49) == res); - - true -} diff --git a/tests/src/fixed_point/ufp64_pow_test/tests/mod.rs b/tests/src/fixed_point/ufp64_pow_test/tests/mod.rs deleted file mode 100644 index 14b79985..00000000 --- a/tests/src/fixed_point/ufp64_pow_test/tests/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64Pow", - abi = "src/fixed_point/ufp64_pow_test/out/release/ufp64_pow_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_pow_test_script() { - let path_to_bin = "src/fixed_point/ufp64_pow_test/out/release/ufp64_pow_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64Pow::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_root_test/.gitignore b/tests/src/fixed_point/ufp64_root_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_root_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_root_test/Forc.toml b/tests/src/fixed_point/ufp64_root_test/Forc.toml deleted file mode 100644 index 0357327c..00000000 --- a/tests/src/fixed_point/ufp64_root_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_root_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_root_test/mod.rs b/tests/src/fixed_point/ufp64_root_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_root_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_root_test/src/main.sw b/tests/src/fixed_point/ufp64_root_test/src/main.sw deleted file mode 100644 index e1694e17..00000000 --- a/tests/src/fixed_point/ufp64_root_test/src/main.sw +++ /dev/null @@ -1,28 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - let one = UFP64::from_uint(1); - let mut res = UFP64::sqrt(one); - assert(one == res); - - let ufp64_100 = UFP64::from_uint(100); - res = UFP64::sqrt(ufp64_100); - assert(UFP64::from_uint(10) == res); - - let ufp64_121 = UFP64::from_uint(121); - res = UFP64::sqrt(ufp64_121); - assert(UFP64::from_uint(11) == res); - - let ufp64_169 = UFP64::from_uint(169); - res = UFP64::sqrt(ufp64_169); - assert(UFP64::from_uint(13) == res); - - let ufp64_49 = UFP64::from_uint(49); - res = UFP64::sqrt(ufp64_49); - assert(UFP64::from_uint(7) == res); - - true -} diff --git a/tests/src/fixed_point/ufp64_root_test/tests/mod.rs b/tests/src/fixed_point/ufp64_root_test/tests/mod.rs deleted file mode 100644 index 5df07ee0..00000000 --- a/tests/src/fixed_point/ufp64_root_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64Root", - abi = "src/fixed_point/ufp64_root_test/out/release/ufp64_root_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_root_test_script() { - let path_to_bin = "src/fixed_point/ufp64_root_test/out/release/ufp64_root_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64Root::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ufp64_test/.gitignore b/tests/src/fixed_point/ufp64_test/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/fixed_point/ufp64_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/fixed_point/ufp64_test/Forc.toml b/tests/src/fixed_point/ufp64_test/Forc.toml deleted file mode 100644 index 7a08c5ea..00000000 --- a/tests/src/fixed_point/ufp64_test/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "ufp64_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp64_test/mod.rs b/tests/src/fixed_point/ufp64_test/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/fixed_point/ufp64_test/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/fixed_point/ufp64_test/src/main.sw b/tests/src/fixed_point/ufp64_test/src/main.sw deleted file mode 100644 index c76d2ed8..00000000 --- a/tests/src/fixed_point/ufp64_test/src/main.sw +++ /dev/null @@ -1,70 +0,0 @@ -script; - -use sway_libs::fixed_point::ufp64::UFP64; -use std::assert::assert; - -fn main() -> bool { - // arithmetic - let one = UFP64::from_uint(1); - let two = UFP64::from_uint(2); - let mut res = two + one; - assert(UFP64::from_uint(3) == res); - - let ufp_64_10 = UFP64::from_uint(10); - res = ufp_64_10 + two; - assert(UFP64::from_uint(12) == res); - - let ufp_64_48 = UFP64::from_uint(48); - let six = UFP64::from_uint(6); - res = ufp_64_48 - six; - assert(UFP64::from_uint(42) == res); - - let ufp_64_169 = UFP64::from_uint(169); - let ufp_64_13 = UFP64::from_uint(13); - res = ufp_64_169 - ufp_64_13; - assert(UFP64::from_uint(156) == res); - - // recip - let mut value = UFP64::from(1 << 32 + 3); - res = UFP64::recip(value); - assert(UFP64::from(536870912) == res); - - // trunc - value = UFP64::from((1 << 32) + 3); - res = value.trunc(); - assert(UFP64::from_uint(1) == res); - - // floor - value = UFP64::from((1 << 32) + 3); - res = value.floor(); - assert(UFP64::from_uint(1) == res); - - // fract - value = UFP64::from((1 << 32) + 3); - res = value.fract(); - assert(UFP64::from(3) == res); - - value = UFP64::from_uint(1); - res = value.fract(); - assert(UFP64::from_uint(0) == res); - - // ceil - value = UFP64::from((1 << 32) + 3); - res = value.ceil(); - assert(UFP64::from_uint(2) == res); - - value = UFP64::from_uint(1); - res = value.ceil(); - assert(UFP64::from_uint(1) == res); - - // round - value = UFP64::from((1 << 32) + 3); - res = value.round(); - assert(UFP64::from_uint(1) == res); - - value = UFP64::from((1 << 32) + (1 << 31) + 1); - res = value.round(); - assert(UFP64::from_uint(2) == res); - - true -} diff --git a/tests/src/fixed_point/ufp64_test/tests/mod.rs b/tests/src/fixed_point/ufp64_test/tests/mod.rs deleted file mode 100644 index 570a535c..00000000 --- a/tests/src/fixed_point/ufp64_test/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "TestUfp64", - abi = "src/fixed_point/ufp64_test/out/release/ufp64_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_ufp64_test_script() { - let path_to_bin = "src/fixed_point/ufp64_test/out/release/ufp64_test.bin"; - - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = TestUfp64::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/harness.rs b/tests/src/harness.rs index dd884489..7ae34127 100644 --- a/tests/src/harness.rs +++ b/tests/src/harness.rs @@ -1,10 +1,9 @@ // Add test modules here: - mod admin; mod bytecode; -mod fixed_point; mod merkle_proof; mod native_asset; mod ownership; mod reentrancy; mod signed_integers; +mod upgradability; diff --git a/tests/src/native_asset/tests/functions/metadata.rs b/tests/src/native_asset/tests/functions/metadata.rs index bdaa5773..19a7c5a0 100644 --- a/tests/src/native_asset/tests/functions/metadata.rs +++ b/tests/src/native_asset/tests/functions/metadata.rs @@ -8,7 +8,6 @@ mod success { use super::*; - #[ignore] #[tokio::test] async fn gets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -26,7 +25,6 @@ mod success { ); } - #[ignore] #[tokio::test] async fn gets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -60,7 +58,6 @@ mod success { ); } - #[ignore] #[tokio::test] async fn gets_multiple_types() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -68,8 +65,10 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::Int(1); - let metadata3 = - Metadata::Bytes(Bytes::from_hex_str("bytes").expect("failed to conver to bytes")); + let metadata3 = Metadata::Bytes( + Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") + .expect("failed to convert to bytes"), + ); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); diff --git a/tests/src/native_asset/tests/functions/set_metadata.rs b/tests/src/native_asset/tests/functions/set_metadata.rs index 56bc276d..6b257ca1 100644 --- a/tests/src/native_asset/tests/functions/set_metadata.rs +++ b/tests/src/native_asset/tests/functions/set_metadata.rs @@ -1,85 +1,157 @@ use crate::native_asset::tests::utils::{ interface::{metadata, set_metadata}, - setup::{defaults, get_asset_id, setup, Metadata}, + setup::{defaults, get_asset_id, setup, Metadata, SetMetadataEvent}, }; -use fuels::types::{Bytes, Bytes32}; +use fuels::types::{Bytes, Bytes32, Identity}; mod success { use super::*; - #[ignore] #[tokio::test] async fn sets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( - metadata(&instance_1, asset_id_1, key).await, - Some(metadata1) + metadata(&instance_1, asset_id_1, key.clone()).await, + Some(metadata1.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1, + key: key + } ); } - #[ignore] #[tokio::test] async fn sets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, - Some(metadata1) + Some(metadata1.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1, + key: key.clone() + } ); assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_2, key.clone()).await, - Some(metadata2) + Some(metadata2.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_2, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2, + key: key.clone() + } ); let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + assert_eq!( + metadata(&instance_1, asset_id_3, key.clone()).await, + Some(metadata3.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( - metadata(&instance_1, asset_id_3, key).await, - Some(metadata3) + *event, + SetMetadataEvent { + asset: asset_id_3, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key + } ); } - #[ignore] #[tokio::test] async fn does_not_overwrite_other_names() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1.clone(), key.clone()).await, Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1.clone(), + key: key.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, @@ -90,9 +162,24 @@ mod success { Some(metadata2.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_2, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2.clone(), + key: key.clone() + } + ); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, @@ -103,34 +190,65 @@ mod success { Some(metadata2) ); assert_eq!( - metadata(&instance_1, asset_id_3, key).await, - Some(metadata3) + metadata(&instance_1, asset_id_3, key.clone()).await, + Some(metadata3.clone()) + ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_3, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key + } ); } - #[ignore] #[tokio::test] async fn sets_multiple_types() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::Int(1); - let metadata3 = - Metadata::Bytes(Bytes::from_hex_str("bytes").expect("failed to conver to bytes")); + let metadata3 = Metadata::Bytes( + Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") + .expect("failed to convert to bytes"), + ); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); assert_eq!(metadata(&instance_1, asset_id_1, key1.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata1.clone(), + key: key1.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_1, key2.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, Some(metadata2.clone()) @@ -140,11 +258,26 @@ mod success { Some(metadata1.clone()) ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata2.clone(), + key: key2.clone() + } + ); + assert_eq!(metadata(&instance_1, asset_id_1, key3.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; + let response = set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; assert_eq!( - metadata(&instance_1, asset_id_1, key3).await, - Some(metadata3) + metadata(&instance_1, asset_id_1, key3.clone()).await, + Some(metadata3.clone()) ); assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, @@ -154,5 +287,20 @@ mod success { metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1) ); + + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + sender: Identity::Address(owner_wallet.address().into()), + metadata: metadata3, + key: key3 + } + ); } } diff --git a/tests/src/signed_integers/mod.rs b/tests/src/signed_integers/mod.rs index 019485d5..e969e9d5 100644 --- a/tests/src/signed_integers/mod.rs +++ b/tests/src/signed_integers/mod.rs @@ -1,11 +1,12 @@ mod signed_i128; +mod signed_i128_wrapping_neg; mod signed_i16; +mod signed_i16_wrapping_neg; mod signed_i256; +mod signed_i256_wrapping_neg; mod signed_i32; +mod signed_i32_wrapping_neg; mod signed_i64; +mod signed_i64_wrapping_neg; mod signed_i8; - -mod signed_i16_twos_complement; -mod signed_i32_twos_complement; -mod signed_i64_twos_complement; -mod signed_i8_twos_complement; +mod signed_i8_wrapping_neg; diff --git a/tests/src/signed_integers/signed_i128/src/main.sw b/tests/src/signed_integers/signed_i128/src/main.sw index 996a7b09..681271b0 100644 --- a/tests/src/signed_integers/signed_i128/src/main.sw +++ b/tests/src/signed_integers/signed_i128/src/main.sw @@ -2,37 +2,170 @@ script; use sway_libs::signed_integers::i128::I128; use std::u128::U128; +use std::convert::*; fn main() -> bool { let u128_one = U128::from((0, 1)); let u128_two = U128::from((0, 2)); - let one = I128::from(u128_one); - let mut res = one + I128::from(u128_one); - assert(res == I128::from(u128_two)); + let one = I128::try_from(u128_one).unwrap(); + let mut res = one + I128::try_from(u128_one).unwrap(); + assert(res == I128::try_from(u128_two).unwrap()); let u128_10 = U128::from((0, 10)); let u128_11 = U128::from((0, 11)); - res = I128::from(u128_10) - I128::from(u128_11); + res = I128::try_from(u128_10).unwrap() - I128::try_from(u128_11).unwrap(); assert(res.underlying().lower() == u64::max()); - res = I128::from(u128_10) * I128::neg_from(u128_one); - assert(res == I128::neg_from(u128_10)); + res = I128::try_from(u128_10).unwrap() * I128::neg_try_from(u128_one).unwrap(); + assert(res == I128::neg_try_from(u128_10).unwrap()); - res = I128::from(u128_10) * I128::from(u128_10); + res = I128::try_from(u128_10).unwrap() * I128::try_from(u128_10).unwrap(); let u128_100 = U128::from((0, 100)); - assert(res == I128::from(u128_100)); + assert(res == I128::try_from(u128_100).unwrap()); let u128_lower_max_u64 = U128::from((0, u64::max())); - res = I128::from(u128_10) / I128::from(u128_lower_max_u64); - assert(res == I128::neg_from(u128_10)); + res = I128::try_from(u128_10).unwrap() / I128::try_from(u128_lower_max_u64).unwrap(); + assert(res == I128::neg_try_from(u128_10).unwrap()); let u128_5 = U128::from((0, 5)); let u128_2 = U128::from((0, 2)); - res = I128::from(u128_10) / I128::from(u128_5); - assert(res == I128::from(u128_2)); + res = I128::try_from(u128_10).unwrap() / I128::try_from(u128_5).unwrap(); + assert(res == I128::try_from(u128_2).unwrap()); + + // Subtraction tests + let pos1 = I128::try_from(U128::from((0, 1))).unwrap(); + let pos2 = I128::try_from(U128::from((0, 2))).unwrap(); + let neg1 = I128::neg_try_from(U128::from((0, 1))).unwrap(); + let neg2 = I128::neg_try_from(U128::from((0, 2))).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + let res1_2 = pos2 - pos1; + assert(res1 == I128::neg_try_from(U128::from((0, 1))).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I128::try_from(U128::from((0, 1))).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I128::try_from(U128::from((0, 2))).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I128::neg_try_from(U128::from((0, 2))).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I128::try_from(U128::from((0, 1))).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I128::neg_try_from(U128::from((0, 1))).unwrap()); + + // OrqEq Tests + let one_1 = I128::try_from(U128::from((0, 1))).unwrap(); + let one_2 = I128::try_from(U128::from((0, 1))).unwrap(); + let neg_one_1 = I128::neg_try_from(U128::from((0, 1))).unwrap(); + let neg_one_2 = I128::neg_try_from(U128::from((0, 1))).unwrap(); + let max_1 = I128::max(); + let max_2 = I128::max(); + let min_1 = I128::min(); + let min_2 = I128::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I128::indent(); + + let neg_try_from_zero = I128::neg_try_from(U128::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I128::zero()); + + let neg_try_from_one = I128::neg_try_from(U128::from((0, 1))); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I128::indent() - U128::from((0, 1))); + + let neg_try_from_max = I128::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == U128::min()); + + let neg_try_from_overflow = I128::neg_try_from(indent + U128::from((0, 1))); + assert(neg_try_from_overflow.is_none()); + + // Test into I128 + let indent: U128 = I128::indent(); + + let i128_max_try_from = I128::try_from(indent); + assert(i128_max_try_from.is_some()); + assert(i128_max_try_from.unwrap() == I128::max()); + + let i128_min_try_from = I128::try_from(U128::min()); + assert(i128_min_try_from.is_some()); + assert(i128_min_try_from.unwrap() == I128::zero()); + + let i128_overflow_try_from = I128::try_from(indent + U128::from((0, 1))); + assert(i128_overflow_try_from.is_none()); + + let i128_max_try_into: Option = indent.try_into(); + assert(i128_max_try_into.is_some()); + assert(i128_max_try_into.unwrap() == I128::max()); + + let i128_min_try_into: Option = U128::min().try_into(); + assert(i128_min_try_into.is_some()); + assert(i128_min_try_into.unwrap() == I128::zero()); + + let i128_overflow_try_into: Option = (indent + U128::from((0, 1))).try_into(); + assert(i128_overflow_try_into.is_none()); + + // Test into U128 + let zero = I128::zero(); + let negative = I128::neg_try_from(U128::from((0, 1))).unwrap(); + let max = I128::max(); + + let U128_max_try_from: Option = U128::try_from(max); + assert(U128_max_try_from.is_some()); + assert(U128_max_try_from.unwrap() == indent); + + let U128_min_try_from: Option = U128::try_from(zero); + assert(U128_min_try_from.is_some()); + assert(U128_min_try_from.unwrap() == U128::zero()); + + let U128_overflow_try_from: Option = U128::try_from(negative); + assert(U128_overflow_try_from.is_none()); + + let U128_max_try_into: Option = zero.try_into(); + assert(U128_max_try_into.is_some()); + assert(U128_max_try_into.unwrap() == indent); + + let U128_min_try_into: Option = zero.try_into(); + assert(U128_min_try_into.is_some()); + assert(U128_min_try_into.unwrap() == U128::zero()); + + let U128_overflow_try_into: Option = negative.try_into(); + assert(U128_overflow_try_into.is_none()); true } diff --git a/tests/src/signed_integers/signed_i128_twos_complement/.gitignore b/tests/src/signed_integers/signed_i128_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i128_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i128_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i128_twos_complement/Forc.toml deleted file mode 100644 index 981e3107..00000000 --- a/tests/src/signed_integers/signed_i128_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i128_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i128_twos_complement/mod.rs b/tests/src/signed_integers/signed_i128_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i128_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i128_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i128_twos_complement/src/main.sw deleted file mode 100644 index b08bbac4..00000000 --- a/tests/src/signed_integers/signed_i128_twos_complement/src/main.sw +++ /dev/null @@ -1,31 +0,0 @@ -script; - -use sway_libs::signed_integers::i128::I128; -use std::u128::U128; - -fn main() -> bool { - let u_one = U128::from((0, 1)); - let one = I128::from(u_one); - let mut res = one + I128::from(U128::from((0, 1))); - assert(res.twos_complement() == I128::from(U128::from((0, 2)))); - - res = I128::from(U128::from((0, 10))); - assert(res.twos_complement() == I128::from(U128::from((0, 10)))); - - res = I128::neg_from(U128::from((0, 5))); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U128::max()); - - res = I128::neg_from(U128::from((0, 27))); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U128::max()); - - res = I128::neg_from(U128::from((0, 110))); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U128::max()); - - res = I128::neg_from(U128::from((0, 93))); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U128::max()); - - res = I128::neg_from(U128::from((0, 78))); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U128::max()); - - true -} diff --git a/tests/src/signed_integers/signed_i128_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i128_twos_complement/tests/mod.rs deleted file mode 100644 index 1f4c3b4d..00000000 --- a/tests/src/signed_integers/signed_i128_twos_complement/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi128TwosComplement", - abi = "src/signed_integers/signed_i128_twos_complement/out/release/i128_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i128_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i128_twos_complement/out/release/i128_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await; - - let instance = Testi128TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp128_div_test/.gitignore b/tests/src/signed_integers/signed_i128_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp128_div_test/.gitignore rename to tests/src/signed_integers/signed_i128_wrapping_neg/.gitignore diff --git a/tests/src/signed_integers/signed_i128_wrapping_neg/Forc.toml b/tests/src/signed_integers/signed_i128_wrapping_neg/Forc.toml new file mode 100644 index 00000000..97be834a --- /dev/null +++ b/tests/src/signed_integers/signed_i128_wrapping_neg/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i128_wrapping_neg_test" + +[dependencies] +sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_div_test/mod.rs b/tests/src/signed_integers/signed_i128_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp64_div_test/mod.rs rename to tests/src/signed_integers/signed_i128_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i128_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i128_wrapping_neg/src/main.sw new file mode 100644 index 00000000..802d8705 --- /dev/null +++ b/tests/src/signed_integers/signed_i128_wrapping_neg/src/main.sw @@ -0,0 +1,61 @@ +script; + +use sway_libs::signed_integers::i128::I128; +use std::u128::U128; + +fn main() -> bool { + let one = I128::try_from(U128::from(1u64)).unwrap(); + let neg_one = I128::neg_try_from(U128::from(1u64)).unwrap(); + + let two = I128::try_from(U128::from(2u64)).unwrap(); + let neg_two = I128::neg_try_from(U128::from(2u64)).unwrap(); + + let ten = I128::try_from(U128::from(10u64)).unwrap(); + let neg_ten = I128::neg_try_from(U128::from(10u64)).unwrap(); + + let twenty_seven = I128::try_from(U128::from(27u64)).unwrap(); + let neg_twenty_seven = I128::neg_try_from(U128::from(27u64)).unwrap(); + + let ninty_three = I128::try_from(U128::from(93u64)).unwrap(); + let neg_ninty_three = I128::neg_try_from(U128::from(93u64)).unwrap(); + + let zero = I128::try_from(U128::zero()).unwrap(); + let max = I128::max(); + let min = I128::min(); + let neg_min_plus_one = I128::min() + I128::try_from(U128::from((0, 1))).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i128_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i128_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..00132f65 --- /dev/null +++ b/tests/src/signed_integers/signed_i128_wrapping_neg/tests/mod.rs @@ -0,0 +1,23 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi128WrappingNeg", + abi = + "src/signed_integers/signed_i128_wrapping_neg/out/release/i128_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_i128_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i128_wrapping_neg/out/release/i128_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi128WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/signed_integers/signed_i16/src/main.sw b/tests/src/signed_integers/signed_i16/src/main.sw index f2e085f0..1f56176c 100644 --- a/tests/src/signed_integers/signed_i16/src/main.sw +++ b/tests/src/signed_integers/signed_i16/src/main.sw @@ -1,26 +1,159 @@ script; use sway_libs::signed_integers::i16::I16; +use std::convert::*; fn main() -> bool { - let one = I16::from(1u16); - let mut res = one + I16::from(1u16); - assert(res == I16::from(2u16)); + let one = I16::try_from(1u16).unwrap(); + let mut res = one + I16::try_from(1u16).unwrap(); + assert(res == I16::try_from(2u16).unwrap()); - res = I16::from(10u16) - I16::from(11u16); - assert(res == I16::from(32767u16)); + res = I16::try_from(10u16).unwrap() - I16::try_from(11u16).unwrap(); + assert(res == I16::try_from(32767u16).unwrap()); - res = I16::from(10u16) * I16::neg_from(1u16); - assert(res == I16::neg_from(10u16)); + res = I16::try_from(10u16).unwrap() * I16::neg_try_from(1u16).unwrap(); + assert(res == I16::neg_try_from(10u16).unwrap()); - res = I16::from(10u16) * I16::from(10u16); - assert(res == I16::from(100u16)); + res = I16::try_from(10u16).unwrap() * I16::try_from(10u16).unwrap(); + assert(res == I16::try_from(100u16).unwrap()); - res = I16::from(10u16) / I16::neg_from(1u16); - assert(res == I16::neg_from(10u16)); + res = I16::try_from(10u16).unwrap() / I16::neg_try_from(1u16).unwrap(); + assert(res == I16::neg_try_from(10u16).unwrap()); - res = I16::from(10u16) / I16::from(5u16); - assert(res == I16::from(2u16)); + res = I16::try_from(10u16).unwrap() / I16::try_from(5u16).unwrap(); + assert(res == I16::try_from(2u16).unwrap()); + + // Subtraction tests + let pos1 = I16::try_from(1).unwrap(); + let pos2 = I16::try_from(2).unwrap(); + let neg1 = I16::neg_try_from(1).unwrap(); + let neg2 = I16::neg_try_from(2).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + let res1_2 = pos2 - pos1; + assert(res1 == I16::neg_try_from(1).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I16::try_from(1).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I16::try_from(2).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I16::neg_try_from(2).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I16::try_from(1).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I16::neg_try_from(1).unwrap()); + + // OrqEq Tests + let one_1 = I16::try_from(1u16).unwrap(); + let one_2 = I16::try_from(1u16).unwrap(); + let neg_one_1 = I16::neg_try_from(1u16).unwrap(); + let neg_one_2 = I16::neg_try_from(1u16).unwrap(); + let max_1 = I16::max(); + let max_2 = I16::max(); + let min_1 = I16::min(); + let min_2 = I16::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I16::indent(); + + let neg_try_from_zero = I16::neg_try_from(u16::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I16::zero()); + + let neg_try_from_one = I16::neg_try_from(1u16); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I16::indent() - 1u16); + + let neg_try_from_max = I16::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == u16::min()); + + let neg_try_from_overflow = I16::neg_try_from(indent + 1u16); + assert(neg_try_from_overflow.is_none()); + + // Test into I16 + let indent: u16 = I16::indent(); + + let i16_max_try_from = I16::try_from(indent); + assert(i16_max_try_from.is_some()); + assert(i16_max_try_from.unwrap() == I16::max()); + + let i16_min_try_from = I16::try_from(u16::min()); + assert(i16_min_try_from.is_some()); + assert(i16_min_try_from.unwrap() == I16::zero()); + + let i16_overflow_try_from = I16::try_from(indent + 1); + assert(i16_overflow_try_from.is_none()); + + let i16_max_try_into: Option = indent.try_into(); + assert(i16_max_try_into.is_some()); + assert(i16_max_try_into.unwrap() == I16::max()); + + let i16_min_try_into: Option = u16::min().try_into(); + assert(i16_min_try_into.is_some()); + assert(i16_min_try_into.unwrap() == I16::zero()); + + let i16_overflow_try_into: Option = (indent + 1).try_into(); + assert(i16_overflow_try_into.is_none()); + + // Test into u16 + let zero = I16::zero(); + let negative = I16::neg_try_from(1).unwrap(); + let max = I16::max(); + + let u16_max_try_from: Option = u16::try_from(max); + assert(u16_max_try_from.is_some()); + assert(u16_max_try_from.unwrap() == indent); + + let u16_min_try_from: Option = u16::try_from(zero); + assert(u16_min_try_from.is_some()); + assert(u16_min_try_from.unwrap() == u16::zero()); + + let u16_overflow_try_from: Option = u16::try_from(negative); + assert(u16_overflow_try_from.is_none()); + + let u16_max_try_into: Option = zero.try_into(); + assert(u16_max_try_into.is_some()); + assert(u16_max_try_into.unwrap() == indent); + + let u16_min_try_into: Option = zero.try_into(); + assert(u16_min_try_into.is_some()); + assert(u16_min_try_into.unwrap() == u16::zero()); + + let u16_overflow_try_into: Option = negative.try_into(); + assert(u16_overflow_try_into.is_none()); true } diff --git a/tests/src/signed_integers/signed_i16_twos_complement/.gitignore b/tests/src/signed_integers/signed_i16_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i16_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i16_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i16_twos_complement/Forc.toml deleted file mode 100644 index ea5c3227..00000000 --- a/tests/src/signed_integers/signed_i16_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i16_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i16_twos_complement/mod.rs b/tests/src/signed_integers/signed_i16_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i16_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i16_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i16_twos_complement/src/main.sw deleted file mode 100644 index 9029b999..00000000 --- a/tests/src/signed_integers/signed_i16_twos_complement/src/main.sw +++ /dev/null @@ -1,29 +0,0 @@ -script; - -use sway_libs::signed_integers::i16::I16; - -fn main() -> bool { - let one = I16::from(1u16); - let mut res = one + I16::from(1u16); - assert(res.twos_complement() == I16::from(2u16)); - - res = I16::from(10u16); - assert(res.twos_complement() == I16::from(10u16)); - - res = I16::neg_from(5); - assert(res.twos_complement().underlying() + res.underlying() == u16::max() + 1); - - res = I16::neg_from(27u16); - assert(res.twos_complement().underlying() + res.underlying() == u16::max() + 1); - - res = I16::neg_from(110u16); - assert(res.twos_complement().underlying() + res.underlying() == u16::max() + 1); - - res = I16::neg_from(93u16); - assert(res.twos_complement().underlying() + res.underlying() == u16::max() + 1); - - res = I16::neg_from(78u16); - assert(res.twos_complement().underlying() + res.underlying() == u16::max() + 1); - - true -} diff --git a/tests/src/signed_integers/signed_i16_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i16_twos_complement/tests/mod.rs deleted file mode 100644 index deaee06b..00000000 --- a/tests/src/signed_integers/signed_i16_twos_complement/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi16TwosComplement", - abi = "src/signed_integers/signed_i16_twos_complement/out/release/i16_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i16_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i16_twos_complement/out/release/i16_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = Testi16TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp128_test/.gitignore b/tests/src/signed_integers/signed_i16_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp128_test/.gitignore rename to tests/src/signed_integers/signed_i16_wrapping_neg/.gitignore diff --git a/tests/src/fixed_point/ifp128_div_test/Forc.toml b/tests/src/signed_integers/signed_i16_wrapping_neg/Forc.toml similarity index 82% rename from tests/src/fixed_point/ifp128_div_test/Forc.toml rename to tests/src/signed_integers/signed_i16_wrapping_neg/Forc.toml index 0dcc3274..b06e023a 100644 --- a/tests/src/fixed_point/ifp128_div_test/Forc.toml +++ b/tests/src/signed_integers/signed_i16_wrapping_neg/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "ifp128_div_test" +name = "i16_wrapping_neg_test" [dependencies] sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_exp_test/mod.rs b/tests/src/signed_integers/signed_i16_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp64_exp_test/mod.rs rename to tests/src/signed_integers/signed_i16_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i16_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i16_wrapping_neg/src/main.sw new file mode 100644 index 00000000..50366666 --- /dev/null +++ b/tests/src/signed_integers/signed_i16_wrapping_neg/src/main.sw @@ -0,0 +1,60 @@ +script; + +use sway_libs::signed_integers::i16::I16; + +fn main() -> bool { + let one = I16::try_from(1u16).unwrap(); + let neg_one = I16::neg_try_from(1u16).unwrap(); + + let two = I16::try_from(2u16).unwrap(); + let neg_two = I16::neg_try_from(2u16).unwrap(); + + let ten = I16::try_from(10u16).unwrap(); + let neg_ten = I16::neg_try_from(10u16).unwrap(); + + let twenty_seven = I16::try_from(27u16).unwrap(); + let neg_twenty_seven = I16::neg_try_from(27u16).unwrap(); + + let ninty_three = I16::try_from(93u16).unwrap(); + let neg_ninty_three = I16::neg_try_from(93u16).unwrap(); + + let zero = I16::try_from(0u16).unwrap(); + let max = I16::max(); + let min = I16::min(); + let neg_min_plus_one = I16::min() + I16::try_from(1u16).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i16_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i16_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..9a00a624 --- /dev/null +++ b/tests/src/signed_integers/signed_i16_wrapping_neg/tests/mod.rs @@ -0,0 +1,22 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi16WrappingNeg", + abi = "src/signed_integers/signed_i16_wrapping_neg/out/release/i16_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_signed_i16_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i16_wrapping_neg/out/release/i16_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi16WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/signed_integers/signed_i256/src/main.sw b/tests/src/signed_integers/signed_i256/src/main.sw index 45ad634c..1b6cf600 100644 --- a/tests/src/signed_integers/signed_i256/src/main.sw +++ b/tests/src/signed_integers/signed_i256/src/main.sw @@ -1,72 +1,204 @@ script; +use std::convert::*; use sway_libs::signed_integers::i256::I256; fn main() -> bool { let parts_one = (0, 0, 0, 1); let parts_two = (0, 0, 0, 2); - let u128_one = asm(r1: parts_one) { + let u256_one = asm(r1: parts_one) { r1: u256 }; - let u128_two = asm(r1: parts_two) { + let u256_two = asm(r1: parts_two) { r1: u256 }; - let one = I256::from(u128_one); - let mut res = one + I256::from(u128_one); - assert(res == I256::from(u128_two)); + let one = I256::try_from(u256_one).unwrap(); + let mut res = one + I256::try_from(u256_one).unwrap(); + assert(res == I256::try_from(u256_two).unwrap()); let parts_10 = (0, 0, 0, 10); - let u128_10 = asm(r1: parts_10) { + let u256_10 = asm(r1: parts_10) { r1: u256 }; let parts_11 = (0, 0, 0, 11); - let u128_11 = asm(r1: parts_11) { + let u256_11 = asm(r1: parts_11) { r1: u256 }; - res = I256::from(u128_10) - I256::from(u128_11); + res = I256::try_from(u256_10).unwrap() - I256::try_from(u256_11).unwrap(); let (a, b, c, d) = asm(r1: res) { r1: (u64, u64, u64, u64) }; assert(c == u64::max()); assert(d == u64::max()); - res = I256::from(u128_10) * I256::neg_from(u128_one); - assert(res == I256::neg_from(u128_10)); + res = I256::try_from(u256_10).unwrap() * I256::neg_try_from(u256_one).unwrap(); + assert(res == I256::neg_try_from(u256_10).unwrap()); - res = I256::from(u128_10) * I256::from(u128_10); + res = I256::try_from(u256_10).unwrap() * I256::try_from(u256_10).unwrap(); let parts_100 = (0, 0, 0, 100); - let u128_100 = asm(r1: parts_100) { + let u256_100 = asm(r1: parts_100) { r1: u256 }; - assert(res == I256::from(u128_100)); + assert(res == I256::try_from(u256_100).unwrap()); let parts_lower_max_u64 = (0, 0, 0, u64::max()); - let u128_lower_max_u64 = asm(r1: parts_lower_max_u64) { + let u256_lower_max_u64 = asm(r1: parts_lower_max_u64) { r1: u256 }; - res = I256::from(u128_10) / I256::from(u128_lower_max_u64); - assert(res == I256::neg_from(u128_10)); + res = I256::try_from(u256_10).unwrap() / I256::try_from(u256_lower_max_u64).unwrap(); + assert(res == I256::neg_try_from(u256_10).unwrap()); let parts_5 = (0, 0, 0, 5); - let u128_5 = asm(r1: parts_5) { + let u256_5 = asm(r1: parts_5) { r1: u256 }; let parts_2 = (0, 0, 0, 2); - let u128_2 = asm(r1: parts_2) { + let u256_2 = asm(r1: parts_2) { r1: u256 }; - let i256_10 = I256::from(u128_10); - let i256_5 = I256::from(u128_5); - let i256_2 = I256::from(u128_2); + let i256_10 = I256::try_from(u256_10).unwrap(); + let i256_5 = I256::try_from(u256_5).unwrap(); + let i256_2 = I256::try_from(u256_2).unwrap(); res = i256_10 / i256_5; assert(res == i256_2); + // Subtraction tests + let pos1 = I256::try_from(u256_one).unwrap(); + let pos2 = I256::try_from(u256_two).unwrap(); + let neg1 = I256::neg_try_from(u256_one).unwrap(); + let neg2 = I256::neg_try_from(u256_two).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + assert(res1 == I256::neg_try_from(u256_one).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I256::try_from(u256_one).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I256::try_from(u256_two).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I256::neg_try_from(u256_two).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I256::try_from(u256_one).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I256::neg_try_from(u256_one).unwrap()); + + // OrqEq Tests + let one_1 = I256::try_from(u256_one).unwrap(); + let one_2 = I256::try_from(u256_one).unwrap(); + let neg_one_1 = I256::neg_try_from(u256_one).unwrap(); + let neg_one_2 = I256::neg_try_from(u256_one).unwrap(); + let max_1 = I256::max(); + let max_2 = I256::max(); + let min_1 = I256::min(); + let min_2 = I256::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I256::indent(); + + let neg_try_from_zero = I256::neg_try_from(u256::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I256::zero()); + + let neg_try_from_one = I256::neg_try_from(u256_one); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I256::indent() - u256_one); + + let neg_try_from_max = I256::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == u256::min()); + + let neg_try_from_overflow = I256::neg_try_from(indent + u256_one); + assert(neg_try_from_overflow.is_none()); + + // Test into I256 + let indent: u256 = I256::indent(); + + let i256_max_try_from = I256::try_from(indent); + assert(i256_max_try_from.is_some()); + assert(i256_max_try_from.unwrap() == I256::max()); + + let i256_min_try_from = I256::try_from(u256::min()); + assert(i256_min_try_from.is_some()); + assert(i256_min_try_from.unwrap() == I256::zero()); + + let i256_overflow_try_from = I256::try_from(indent + u256_one); + assert(i256_overflow_try_from.is_none()); + + let i256_max_try_into: Option = indent.try_into(); + assert(i256_max_try_into.is_some()); + assert(i256_max_try_into.unwrap() == I256::max()); + + let i256_min_try_into: Option = u256::min().try_into(); + assert(i256_min_try_into.is_some()); + assert(i256_min_try_into.unwrap() == I256::zero()); + + let i256_overflow_try_into: Option = (indent + u256_one).try_into(); + assert(i256_overflow_try_into.is_none()); + + // Test into u256 + let zero = I256::zero(); + let negative = I256::neg_try_from(u256_one).unwrap(); + let max = I256::max(); + + let u256_max_try_from: Option = u256::try_from(max); + assert(u256_max_try_from.is_some()); + assert(u256_max_try_from.unwrap() == indent); + + let u256_min_try_from: Option = u256::try_from(zero); + assert(u256_min_try_from.is_some()); + assert(u256_min_try_from.unwrap() == u256::zero()); + + let u256_overflow_try_from: Option = u256::try_from(negative); + assert(u256_overflow_try_from.is_none()); + + let u256_max_try_into: Option = zero.try_into(); + assert(u256_max_try_into.is_some()); + assert(u256_max_try_into.unwrap() == indent); + + let u256_min_try_into: Option = zero.try_into(); + assert(u256_min_try_into.is_some()); + assert(u256_min_try_into.unwrap() == u256::zero()); + + let u256_overflow_try_into: Option = negative.try_into(); + assert(u256_overflow_try_into.is_none()); + true } diff --git a/tests/src/signed_integers/signed_i256_twos_complement/.gitignore b/tests/src/signed_integers/signed_i256_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i256_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i256_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i256_twos_complement/Forc.toml deleted file mode 100644 index 60815b83..00000000 --- a/tests/src/signed_integers/signed_i256_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i256_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i256_twos_complement/mod.rs b/tests/src/signed_integers/signed_i256_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i256_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i256_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i256_twos_complement/src/main.sw deleted file mode 100644 index d9199934..00000000 --- a/tests/src/signed_integers/signed_i256_twos_complement/src/main.sw +++ /dev/null @@ -1,61 +0,0 @@ -script; - -use sway_libs::signed_integers::i256::I256; - -fn main() -> bool { - let parts_one = (0, 0, 0, 1); - let parts_two = (0, 0, 0, 2); - let u_one = asm(r1: parts_one) { - r1: u256 - }; - let u_two = asm(r1: parts_two) { - r1: u256 - }; - let one = I256::from(u_one); - let mut res = one + I256::from(u_one); - assert(res.twos_complement() == I256::from(u_two)); - - let parts_10 = (0, 0, 0, 10); - let u_10 = asm(r1: parts_10) { - r1: u256 - }; - res = I256::from(u_10); - assert(res.twos_complement() == I256::from(u_10)); - - let parts_5 = (0, 0, 0, 5); - let u_5 = asm(r1: parts_5) { - r1: u256 - }; - res = I256::neg_from(u_5); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U256::max()); - - let parts_27 = (0, 0, 0, 27); - let u_27 = asm(r1: parts_27) { - r1: u256 - }; - res = I256::neg_from(u_27); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U256::max()); - - let parts_110 = (0, 0, 0, 110); - let u_110 = asm(r1: parts_110) { - r1: u256 - }; - res = I256::neg_from(u_110); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U256::max()); - - let parts_93 = (0, 0, 0, 93); - let u_93 = asm(r1: parts_93) { - r1: u256 - }; - res = I256::neg_from(parts_93); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U256::max()); - - let parts_78 = (0, 0, 0, 78); - let u_78 = asm(r1: parts_78) { - r1: u256 - }; - res = I256::neg_from(u_78); - assert(res.twos_complement().underlying() - u_one + res.underlying() == U256::max()); - - true -} diff --git a/tests/src/signed_integers/signed_i256_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i256_twos_complement/tests/mod.rs deleted file mode 100644 index 86b5d93d..00000000 --- a/tests/src/signed_integers/signed_i256_twos_complement/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi256TwosComplement", - abi = "src/signed_integers/signed_i256_twos_complement/out/release/i256_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i256_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i256_twos_complement/out/release/i256_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await; - - let instance = Testi256TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp256_div_test/.gitignore b/tests/src/signed_integers/signed_i256_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp256_div_test/.gitignore rename to tests/src/signed_integers/signed_i256_wrapping_neg/.gitignore diff --git a/tests/src/signed_integers/signed_i256_wrapping_neg/Forc.toml b/tests/src/signed_integers/signed_i256_wrapping_neg/Forc.toml new file mode 100644 index 00000000..85795249 --- /dev/null +++ b/tests/src/signed_integers/signed_i256_wrapping_neg/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i256_wrapping_neg_test" + +[dependencies] +sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_mul_test/mod.rs b/tests/src/signed_integers/signed_i256_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp64_mul_test/mod.rs rename to tests/src/signed_integers/signed_i256_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i256_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i256_wrapping_neg/src/main.sw new file mode 100644 index 00000000..5260df80 --- /dev/null +++ b/tests/src/signed_integers/signed_i256_wrapping_neg/src/main.sw @@ -0,0 +1,81 @@ +script; + +use sway_libs::signed_integers::i256::I256; + +fn main() -> bool { + let parts_one = (0, 0, 0, 1); + let parts_two = (0, 0, 0, 2); + let parts_ten = (0, 0, 0, 10); + let parts_twenty_seven = (0, 0, 0, 27); + let parts_ninty_three = (0, 0, 0, 93); + let u_one = asm(r1: parts_one) { + r1: u256 + }; + let u_two = asm(r1: parts_two) { + r1: u256 + }; + let u_ten = asm(r1: parts_ten) { + r1: u256 + }; + let u_twenty_seven = asm(r1: parts_twenty_seven) { + r1: u256 + }; + let u_ninty_three = asm(r1: parts_ninty_three) { + r1: u256 + }; + + let one = I256::try_from(u_one).unwrap(); + let neg_one = I256::neg_try_from(u_one).unwrap(); + + let two = I256::try_from(u_two).unwrap(); + let neg_two = I256::neg_try_from(u_two).unwrap(); + + let ten = I256::try_from(u_ten).unwrap(); + let neg_ten = I256::neg_try_from(u_ten).unwrap(); + + let twenty_seven = I256::try_from(u_twenty_seven).unwrap(); + let neg_twenty_seven = I256::neg_try_from(u_twenty_seven).unwrap(); + + let ninty_three = I256::try_from(u_ninty_three).unwrap(); + let neg_ninty_three = I256::neg_try_from(u_ninty_three).unwrap(); + + let zero = I256::try_from(u256::zero()).unwrap(); + let max = I256::max(); + let min = I256::min(); + let neg_min_plus_one = I256::min() + I256::try_from(u_one).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i256_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i256_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..6bdf83b7 --- /dev/null +++ b/tests/src/signed_integers/signed_i256_wrapping_neg/tests/mod.rs @@ -0,0 +1,23 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi256WrappingNeg", + abi = + "src/signed_integers/signed_i256_wrapping_neg/out/release/i256_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_i256_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i256_wrapping_neg/out/release/i256_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi256WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/signed_integers/signed_i32/src/main.sw b/tests/src/signed_integers/signed_i32/src/main.sw index 437ab4f0..ead519ba 100644 --- a/tests/src/signed_integers/signed_i32/src/main.sw +++ b/tests/src/signed_integers/signed_i32/src/main.sw @@ -1,26 +1,159 @@ script; use sway_libs::signed_integers::i32::I32; +use std::convert::*; fn main() -> bool { - let one = I32::from(1u32); - let mut res = one + I32::from(1u32); - assert(res == I32::from(2u32)); + let one = I32::try_from(1u32).unwrap(); + let mut res = one + I32::try_from(1u32).unwrap(); + assert(res == I32::try_from(2u32).unwrap()); - res = I32::from(10u32) - I32::from(11u32); - assert(res == I32::from(2147483647u32)); + res = I32::try_from(10u32).unwrap() - I32::try_from(11u32).unwrap(); + assert(res == I32::try_from(2147483647u32).unwrap()); - res = I32::from(10u32) * I32::from(1u32); - assert(res == I32::neg_from(10u32)); + res = I32::try_from(10u32).unwrap() * I32::try_from(1u32).unwrap(); + assert(res == I32::neg_try_from(10u32).unwrap()); - res = I32::from(10u32) * I32::from(10u32); - assert(res == I32::from(100u32)); + res = I32::try_from(10u32).unwrap() * I32::try_from(10u32).unwrap(); + assert(res == I32::try_from(100u32).unwrap()); - res = I32::from(10u32) / I32::neg_from(1u32); - assert(res == I32::neg_from(10u32)); + res = I32::try_from(10u32).unwrap() / I32::neg_try_from(1u32).unwrap(); + assert(res == I32::neg_try_from(10u32).unwrap()); - res = I32::from(10u32) / I32::from(5u32); - assert(res == I32::from(2u32)); + res = I32::try_from(10u32).unwrap() / I32::try_from(5u32).unwrap(); + assert(res == I32::try_from(2u32).unwrap()); + + // Subtraction Tests + let pos1 = I32::try_from(1).unwrap(); + let pos2 = I32::try_from(2).unwrap(); + let neg1 = I32::neg_try_from(1).unwrap(); + let neg2 = I32::neg_try_from(2).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + let res1_2 = pos2 - pos1; + assert(res1 == I32::neg_try_from(1).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I32::try_from(1).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I32::try_from(2).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I32::neg_try_from(2).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I32::try_from(1).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I32::neg_try_from(1).unwrap()); + + // OrqEq Tests + let one_1 = I32::try_from(1u32).unwrap(); + let one_2 = I32::try_from(1u32).unwrap(); + let neg_one_1 = I32::neg_try_from(1u32).unwrap(); + let neg_one_2 = I32::neg_try_from(1u32).unwrap(); + let max_1 = I32::max(); + let max_2 = I32::max(); + let min_1 = I32::min(); + let min_2 = I32::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I32::indent(); + + let neg_try_from_zero = I32::neg_try_from(u32::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I32::zero()); + + let neg_try_from_one = I32::neg_try_from(1u32); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I32::indent() - 1u32); + + let neg_try_from_max = I32::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == u32::min()); + + let neg_try_from_overflow = I32::neg_try_from(indent + 1u32); + assert(neg_try_from_overflow.is_none()); + + // Test into I32 + let indent: u32 = I32::indent(); + + let i32_max_try_from = I32::try_from(indent); + assert(i32_max_try_from.is_some()); + assert(i32_max_try_from.unwrap() == I32::max()); + + let i32_min_try_from = I32::try_from(u32::min()); + assert(i32_min_try_from.is_some()); + assert(i32_min_try_from.unwrap() == I32::zero()); + + let i32_overflow_try_from = I32::try_from(indent + 1); + assert(i32_overflow_try_from.is_none()); + + let i32_max_try_into: Option = indent.try_into(); + assert(i32_max_try_into.is_some()); + assert(i32_max_try_into.unwrap() == I32::max()); + + let i32_min_try_into: Option = u32::min().try_into(); + assert(i32_min_try_into.is_some()); + assert(i32_min_try_into.unwrap() == I32::zero()); + + let i32_overflow_try_into: Option = (indent + 1).try_into(); + assert(i32_overflow_try_into.is_none()); + + // Test into u32 + let zero = I32::zero(); + let negative = I32::neg_try_from(1).unwrap(); + let max = I32::max(); + + let u32_max_try_from: Option = u32::try_from(max); + assert(u32_max_try_from.is_some()); + assert(u32_max_try_from.unwrap() == indent); + + let u32_min_try_from: Option = u32::try_from(zero); + assert(u32_min_try_from.is_some()); + assert(u32_min_try_from.unwrap() == u32::zero()); + + let u32_overflow_try_from: Option = u32::try_from(negative); + assert(u32_overflow_try_from.is_none()); + + let u32_max_try_into: Option = zero.try_into(); + assert(u32_max_try_into.is_some()); + assert(u32_max_try_into.unwrap() == indent); + + let u32_min_try_into: Option = zero.try_into(); + assert(u32_min_try_into.is_some()); + assert(u32_min_try_into.unwrap() == u32::zero()); + + let u32_overflow_try_into: Option = negative.try_into(); + assert(u32_overflow_try_into.is_none()); true } diff --git a/tests/src/signed_integers/signed_i32_twos_complement/.gitignore b/tests/src/signed_integers/signed_i32_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i32_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i32_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i32_twos_complement/Forc.toml deleted file mode 100644 index 0ce180aa..00000000 --- a/tests/src/signed_integers/signed_i32_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i32_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i32_twos_complement/mod.rs b/tests/src/signed_integers/signed_i32_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i32_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i32_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i32_twos_complement/src/main.sw deleted file mode 100644 index d32e4af6..00000000 --- a/tests/src/signed_integers/signed_i32_twos_complement/src/main.sw +++ /dev/null @@ -1,29 +0,0 @@ -script; - -use sway_libs::signed_integers::i32::I32; - -fn main() -> bool { - let one = I32::from(1u32); - let mut res = one + I32::from(1u32); - assert(res.twos_complement() == I32::from(2u32)); - - res = I32::from(10u32); - assert(res.twos_complement() == I32::from(10u32)); - - res = I32::neg_from(5); - assert(res.twos_complement().underlying() + res.underlying() == u32::max() + 1); - - res = I32::neg_from(27u32); - assert(res.twos_complement().underlying() + res.underlying() == u32::max() + 1); - - res = I32::neg_from(110u32); - assert(res.twos_complement().underlying() + res.underlying() == u32::max() + 1); - - res = I32::neg_from(93u32); - assert(res.twos_complement().underlying() + res.underlying() == u32::max() + 1); - - res = I32::neg_from(78u32); - assert(res.twos_complement().underlying() + res.underlying() == u32::max() + 1); - - true -} diff --git a/tests/src/signed_integers/signed_i32_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i32_twos_complement/tests/mod.rs deleted file mode 100644 index 1974e72b..00000000 --- a/tests/src/signed_integers/signed_i32_twos_complement/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi32TwosComplement", - abi = "src/signed_integers/signed_i32_twos_complement/out/release/i32_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i32_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i32_twos_complement/out/release/i32_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = Testi32TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp256_test/.gitignore b/tests/src/signed_integers/signed_i32_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp256_test/.gitignore rename to tests/src/signed_integers/signed_i32_wrapping_neg/.gitignore diff --git a/tests/src/fixed_point/ifp256_test/Forc.toml b/tests/src/signed_integers/signed_i32_wrapping_neg/Forc.toml similarity index 82% rename from tests/src/fixed_point/ifp256_test/Forc.toml rename to tests/src/signed_integers/signed_i32_wrapping_neg/Forc.toml index f41a4ec7..77f6b6fc 100644 --- a/tests/src/fixed_point/ifp256_test/Forc.toml +++ b/tests/src/signed_integers/signed_i32_wrapping_neg/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "ifp256_test" +name = "i32_wrapping_neg_test" [dependencies] sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_pow_test/mod.rs b/tests/src/signed_integers/signed_i32_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp64_pow_test/mod.rs rename to tests/src/signed_integers/signed_i32_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i32_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i32_wrapping_neg/src/main.sw new file mode 100644 index 00000000..bdb2c19f --- /dev/null +++ b/tests/src/signed_integers/signed_i32_wrapping_neg/src/main.sw @@ -0,0 +1,60 @@ +script; + +use sway_libs::signed_integers::i32::I32; + +fn main() -> bool { + let one = I32::try_from(1u32).unwrap(); + let neg_one = I32::neg_try_from(1u32).unwrap(); + + let two = I32::try_from(2u32).unwrap(); + let neg_two = I32::neg_try_from(2u32).unwrap(); + + let ten = I32::try_from(10u32).unwrap(); + let neg_ten = I32::neg_try_from(10u32).unwrap(); + + let twenty_seven = I32::try_from(27u32).unwrap(); + let neg_twenty_seven = I32::neg_try_from(27u32).unwrap(); + + let ninty_three = I32::try_from(93u32).unwrap(); + let neg_ninty_three = I32::neg_try_from(93u32).unwrap(); + + let zero = I32::try_from(0u32).unwrap(); + let max = I32::max(); + let min = I32::min(); + let neg_min_plus_one = I32::min() + I32::try_from(1u32).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i32_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i32_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..cbf3f824 --- /dev/null +++ b/tests/src/signed_integers/signed_i32_wrapping_neg/tests/mod.rs @@ -0,0 +1,22 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi32WrappingNeg", + abi = "src/signed_integers/signed_i32_wrapping_neg/out/release/i32_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_i32_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i32_wrapping_neg/out/release/i32_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi32WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/signed_integers/signed_i64/src/main.sw b/tests/src/signed_integers/signed_i64/src/main.sw index 1a3ae3ac..f6656df3 100644 --- a/tests/src/signed_integers/signed_i64/src/main.sw +++ b/tests/src/signed_integers/signed_i64/src/main.sw @@ -1,25 +1,158 @@ script; use sway_libs::signed_integers::i64::I64; +use std::convert::*; fn main() -> bool { - let one = I64::from(1u64); - let mut res = one + I64::from(1u64); - assert(res == I64::from(2u64)); + let one = I64::try_from(1u64).unwrap(); + let mut res = one + I64::try_from(1u64).unwrap(); + assert(res == I64::try_from(2u64).unwrap()); - res = I64::from(10u64) - I64::from(11u64); - assert(res == I64::from(9223372036854775807u64)); - res = I64::from(10u64) * I64::neg_from(1); - assert(res == I64::neg_from(10)); + res = I64::try_from(10u64).unwrap() - I64::try_from(11u64).unwrap(); + assert(res == I64::try_from(9223372036854775807u64).unwrap()); + res = I64::try_from(10u64).unwrap() * I64::neg_try_from(1).unwrap(); + assert(res == I64::neg_try_from(10).unwrap()); - res = I64::from(10u64) * I64::from(10u64); - assert(res == I64::from(100u64)); + res = I64::try_from(10u64).unwrap() * I64::try_from(10u64).unwrap(); + assert(res == I64::try_from(100u64).unwrap()); - res = I64::from(10u64) / I64::from(9223372036854775807u64); - assert(res == I64::neg_from(10u64)); + res = I64::try_from(10u64).unwrap() / I64::try_from(9223372036854775807u64).unwrap(); + assert(res == I64::neg_try_from(10u64).unwrap()); - res = I64::from(10u64) / I64::from(5u64); - assert(res == I64::from(2u64)); + res = I64::try_from(10u64).unwrap() / I64::try_from(5u64).unwrap(); + assert(res == I64::try_from(2u64).unwrap()); + + // Subtraction Tests + let pos1 = I64::try_from(1).unwrap(); + let pos2 = I64::try_from(2).unwrap(); + let neg1 = I64::neg_try_from(1).unwrap(); + let neg2 = I64::neg_try_from(2).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + let res1_2 = pos2 - pos1; + assert(res1 == I64::neg_try_from(1).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I64::try_from(1).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I64::try_from(2).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I64::neg_try_from(2).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I64::try_from(1).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I64::neg_try_from(1).unwrap()); + + // OrqEq Tests + let one_1 = I64::try_from(1u64).unwrap(); + let one_2 = I64::try_from(1u64).unwrap(); + let neg_one_1 = I64::neg_try_from(1u64).unwrap(); + let neg_one_2 = I64::neg_try_from(1u64).unwrap(); + let max_1 = I64::max(); + let max_2 = I64::max(); + let min_1 = I64::min(); + let min_2 = I64::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I64::indent(); + + let neg_try_from_zero = I64::neg_try_from(u64::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I64::zero()); + + let neg_try_from_one = I64::neg_try_from(1u64); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I64::indent() - 1u64); + + let neg_try_from_max = I64::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == u64::min()); + + let neg_try_from_overflow = I64::neg_try_from(indent + 1u64); + assert(neg_try_from_overflow.is_none()); + + // Test into I64 + let indent: u64 = I64::indent(); + + let i64_max_try_from = I64::try_from(indent); + assert(i64_max_try_from.is_some()); + assert(i64_max_try_from.unwrap() == I64::max()); + + let i64_min_try_from = I64::try_from(u64::min()); + assert(i64_min_try_from.is_some()); + assert(i64_min_try_from.unwrap() == I64::zero()); + + let i64_overflow_try_from = I64::try_from(indent + 1); + assert(i64_overflow_try_from.is_none()); + + let i64_max_try_into: Option = indent.try_into(); + assert(i64_max_try_into.is_some()); + assert(i64_max_try_into.unwrap() == I64::max()); + + let i64_min_try_into: Option = u64::min().try_into(); + assert(i64_min_try_into.is_some()); + assert(i64_min_try_into.unwrap() == I64::zero()); + + let i64_overflow_try_into: Option = (indent + 1).try_into(); + assert(i64_overflow_try_into.is_none()); + + // Test into u64 + let zero = I64::zero(); + let negative = I64::neg_try_from(1).unwrap(); + let max = I64::max(); + + let u64_max_try_from: Option = u64::try_from(max); + assert(u64_max_try_from.is_some()); + assert(u64_max_try_from.unwrap() == indent); + + let u64_min_try_from: Option = u64::try_from(zero); + assert(u64_min_try_from.is_some()); + assert(u64_min_try_from.unwrap() == u64::zero()); + + let u64_overflow_try_from: Option = u64::try_from(negative); + assert(u64_overflow_try_from.is_none()); + + let u64_max_try_into: Option = zero.try_into(); + assert(u64_max_try_into.is_some()); + assert(u64_max_try_into.unwrap() == indent); + + let u64_min_try_into: Option = zero.try_into(); + assert(u64_min_try_into.is_some()); + assert(u64_min_try_into.unwrap() == u64::zero()); + + let u64_overflow_try_into: Option = negative.try_into(); + assert(u64_overflow_try_into.is_none()); true } diff --git a/tests/src/signed_integers/signed_i64_twos_complement/.gitignore b/tests/src/signed_integers/signed_i64_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i64_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i64_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i64_twos_complement/Forc.toml deleted file mode 100644 index b6211748..00000000 --- a/tests/src/signed_integers/signed_i64_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i64_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i64_twos_complement/mod.rs b/tests/src/signed_integers/signed_i64_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i64_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i64_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i64_twos_complement/src/main.sw deleted file mode 100644 index 7d8a5c43..00000000 --- a/tests/src/signed_integers/signed_i64_twos_complement/src/main.sw +++ /dev/null @@ -1,29 +0,0 @@ -script; - -use sway_libs::signed_integers::i64::I64; - -fn main() -> bool { - let one = I64::from(1); - let mut res = one + I64::from(1); - assert(res.twos_complement() == I64::from(2)); - - res = I64::from(10); - assert(res.twos_complement() == I64::from(10)); - - res = I64::neg_from(5); - assert(res.twos_complement().underlying() + res.underlying() == u64::max() + 1); - - res = I64::neg_from(27); - assert(res.twos_complement().underlying() + res.underlying() == u64::max() + 1); - - res = I64::neg_from(110); - assert(res.twos_complement().underlying() + res.underlying() == u64::max() + 1); - - res = I64::neg_from(93); - assert(res.twos_complement().underlying() + res.underlying() == u64::max() + 1); - - res = I64::neg_from(78); - assert(res.twos_complement().underlying() + res.underlying() == u64::max() + 1); - - true -} diff --git a/tests/src/signed_integers/signed_i64_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i64_twos_complement/tests/mod.rs deleted file mode 100644 index fbdddc90..00000000 --- a/tests/src/signed_integers/signed_i64_twos_complement/tests/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi64TwosComplement", - abi = "src/signed_integers/signed_i64_twos_complement/out/release/i64_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i64_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i64_twos_complement/out/release/i64_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = Testi64TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_div_test/.gitignore b/tests/src/signed_integers/signed_i64_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp64_div_test/.gitignore rename to tests/src/signed_integers/signed_i64_wrapping_neg/.gitignore diff --git a/tests/src/fixed_point/ifp128_test/Forc.toml b/tests/src/signed_integers/signed_i64_wrapping_neg/Forc.toml similarity index 82% rename from tests/src/fixed_point/ifp128_test/Forc.toml rename to tests/src/signed_integers/signed_i64_wrapping_neg/Forc.toml index 441e3273..ffeb52f3 100644 --- a/tests/src/fixed_point/ifp128_test/Forc.toml +++ b/tests/src/signed_integers/signed_i64_wrapping_neg/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "ifp128_test" +name = "i64_wrapping_neg_test" [dependencies] sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ifp64_test/mod.rs b/tests/src/signed_integers/signed_i64_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp64_test/mod.rs rename to tests/src/signed_integers/signed_i64_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i64_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i64_wrapping_neg/src/main.sw new file mode 100644 index 00000000..e76f4d5c --- /dev/null +++ b/tests/src/signed_integers/signed_i64_wrapping_neg/src/main.sw @@ -0,0 +1,60 @@ +script; + +use sway_libs::signed_integers::i64::I64; + +fn main() -> bool { + let one = I64::try_from(1u64).unwrap(); + let neg_one = I64::neg_try_from(1u64).unwrap(); + + let two = I64::try_from(2u64).unwrap(); + let neg_two = I64::neg_try_from(2u64).unwrap(); + + let ten = I64::try_from(10u64).unwrap(); + let neg_ten = I64::neg_try_from(10u64).unwrap(); + + let twenty_seven = I64::try_from(27u64).unwrap(); + let neg_twenty_seven = I64::neg_try_from(27u64).unwrap(); + + let ninty_three = I64::try_from(93u64).unwrap(); + let neg_ninty_three = I64::neg_try_from(93u64).unwrap(); + + let zero = I64::try_from(0u64).unwrap(); + let max = I64::max(); + let min = I64::min(); + let neg_min_plus_one = I64::min() + I64::try_from(1).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i64_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i64_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..a2754493 --- /dev/null +++ b/tests/src/signed_integers/signed_i64_wrapping_neg/tests/mod.rs @@ -0,0 +1,22 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi64WrappingNeg", + abi = "src/signed_integers/signed_i64_wrapping_neg/out/release/i64_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_i64_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i64_wrapping_neg/out/release/i64_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi64WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/signed_integers/signed_i8/src/main.sw b/tests/src/signed_integers/signed_i8/src/main.sw index bba63c52..08586d44 100644 --- a/tests/src/signed_integers/signed_i8/src/main.sw +++ b/tests/src/signed_integers/signed_i8/src/main.sw @@ -1,26 +1,158 @@ script; use sway_libs::signed_integers::i8::I8; +use std::convert::*; fn main() -> bool { - let one = I8::from(1u8); - let mut res = one + I8::from(1u8); - assert(res == I8::from(2u8)); + let one = I8::try_from(1u8).unwrap(); + let mut res = one + I8::try_from(1u8).unwrap(); + assert(res == I8::try_from(2u8).unwrap()); - res = I8::from(10u8) - I8::from(11u8); - assert(res == I8::from(127u8)); + res = I8::try_from(10u8).unwrap() - I8::try_from(11u8).unwrap(); + assert(res == I8::try_from(127u8).unwrap()); - res = I8::from(10u8) * I8::from(127u8); - assert(res == I8::from(118u8)); + res = I8::try_from(10u8).unwrap() * I8::try_from(127u8).unwrap(); + assert(res == I8::try_from(118u8).unwrap()); - res = I8::from(10u8) * I8::from(10u8); - assert(res == I8::from(100u8)); + res = I8::try_from(10u8).unwrap() * I8::try_from(10u8).unwrap(); + assert(res == I8::try_from(100u8).unwrap()); - res = I8::from(10u8) / I8::from(127u8); - assert(res == I8::from(118u8)); + res = I8::try_from(10u8).unwrap() / I8::try_from(127u8).unwrap(); + assert(res == I8::try_from(118u8).unwrap()); - res = I8::from(10u8) / I8::from(5u8); - assert(res == I8::from(2u8)); + res = I8::try_from(10u8).unwrap() / I8::try_from(5u8).unwrap(); + assert(res == I8::try_from(2u8).unwrap()); + + // Subtraction Tests + let pos1 = I8::try_from(1).unwrap(); + let pos2 = I8::try_from(2).unwrap(); + let neg1 = I8::neg_try_from(1).unwrap(); + let neg2 = I8::neg_try_from(2).unwrap(); + + // Both positive: + let res1 = pos1 - pos2; + assert(res1 == I8::neg_try_from(1).unwrap()); + + let res2 = pos2 - pos1; + assert(res2 == I8::try_from(1).unwrap()); + + // First positive + let res3 = pos1 - neg1; + assert(res3 == I8::try_from(2).unwrap()); + + // Second positive + let res4 = neg1 - pos1; + assert(res4 == I8::neg_try_from(2).unwrap()); + + // Both negative + let res5 = neg1 - neg2; + assert(res5 == I8::try_from(1).unwrap()); + + let res6 = neg2 - neg1; + assert(res6 == I8::neg_try_from(1).unwrap()); + + // OrqEq Tests + let one_1 = I8::try_from(1u8).unwrap(); + let one_2 = I8::try_from(1u8).unwrap(); + let neg_one_1 = I8::neg_try_from(1u8).unwrap(); + let neg_one_2 = I8::neg_try_from(1u8).unwrap(); + let max_1 = I8::max(); + let max_2 = I8::max(); + let min_1 = I8::min(); + let min_2 = I8::min(); + + assert(one_1 >= one_2); + assert(one_1 <= one_2); + assert(neg_one_1 >= neg_one_2); + assert(neg_one_1 <= neg_one_2); + assert(max_1 >= max_1); + assert(max_1 <= max_1); + assert(min_1 >= min_1); + assert(min_1 <= min_1); + + assert(min_1 <= one_1); + assert(min_1 <= neg_one_1); + assert(min_1 <= max_1); + assert(neg_one_1 <= max_1); + assert(neg_one_1 <= one_1); + assert(one_1 <= max_1); + + assert(max_1 >= one_1); + assert(max_1 >= neg_one_1); + assert(max_1 >= min_1); + assert(one_1 >= neg_one_1); + assert(one_1 >= min_1); + assert(neg_one_1 >= min_1); + + // Test neg try from + let indent = I8::indent(); + + let neg_try_from_zero = I8::neg_try_from(u8::min()); + assert(neg_try_from_zero.is_some()); + assert(neg_try_from_zero.unwrap() == I8::zero()); + + let neg_try_from_one = I8::neg_try_from(1u8); + assert(neg_try_from_one.is_some()); + assert(neg_try_from_one.unwrap().underlying() == I8::indent() - 1u8); + + let neg_try_from_max = I8::neg_try_from(indent); + assert(neg_try_from_max.is_some()); + assert(neg_try_from_max.unwrap().underlying() == u8::min()); + + let neg_try_from_overflow = I8::neg_try_from(indent + 1u8); + assert(neg_try_from_overflow.is_none()); + + // Test into I8 + let indent: u8 = I8::indent(); + + let i8_max_try_from = I8::try_from(indent); + assert(i8_max_try_from.is_some()); + assert(i8_max_try_from.unwrap() == I8::max()); + + let i8_min_try_from = I8::try_from(u8::min()); + assert(i8_min_try_from.is_some()); + assert(i8_min_try_from.unwrap() == I8::zero()); + + let i8_overflow_try_from = I8::try_from(indent + 1); + assert(i8_overflow_try_from.is_none()); + + let i8_max_try_into: Option = indent.try_into(); + assert(i8_max_try_into.is_some()); + assert(i8_max_try_into.unwrap() == I8::max()); + + let i8_min_try_into: Option = u8::min().try_into(); + assert(i8_min_try_into.is_some()); + assert(i8_min_try_into.unwrap() == I8::zero()); + + let i8_overflow_try_into: Option = (indent + 1).try_into(); + assert(i8_overflow_try_into.is_none()); + + // Test into u8 + let zero = I8::zero(); + let negative = I8::neg_try_from(1).unwrap(); + let max = I8::max(); + + let u8_max_try_from: Option = u8::try_from(max); + assert(u8_max_try_from.is_some()); + assert(u8_max_try_from.unwrap() == indent); + + let u8_min_try_from: Option = u8::try_from(zero); + assert(u8_min_try_from.is_some()); + assert(u8_min_try_from.unwrap() == u8::zero()); + + let u8_overflow_try_from: Option = u8::try_from(negative); + assert(u8_overflow_try_from.is_none()); + + let u8_max_try_into: Option = zero.try_into(); + assert(u8_max_try_into.is_some()); + assert(u8_max_try_into.unwrap() == indent); + + let u8_min_try_into: Option = zero.try_into(); + assert(u8_min_try_into.is_some()); + assert(u8_min_try_into.unwrap() == u8::zero()); + + let u8_overflow_try_into: Option = negative.try_into(); + assert(u8_overflow_try_into.is_none()); true } diff --git a/tests/src/signed_integers/signed_i8_twos_complement/.gitignore b/tests/src/signed_integers/signed_i8_twos_complement/.gitignore deleted file mode 100644 index 77d3844f..00000000 --- a/tests/src/signed_integers/signed_i8_twos_complement/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -out -target diff --git a/tests/src/signed_integers/signed_i8_twos_complement/Forc.toml b/tests/src/signed_integers/signed_i8_twos_complement/Forc.toml deleted file mode 100644 index 461e6513..00000000 --- a/tests/src/signed_integers/signed_i8_twos_complement/Forc.toml +++ /dev/null @@ -1,8 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "main.sw" -license = "Apache-2.0" -name = "i8_twos_complement_test" - -[dependencies] -sway_libs = { path = "../../../../libs" } diff --git a/tests/src/signed_integers/signed_i8_twos_complement/mod.rs b/tests/src/signed_integers/signed_i8_twos_complement/mod.rs deleted file mode 100644 index dc39c4cc..00000000 --- a/tests/src/signed_integers/signed_i8_twos_complement/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod tests; diff --git a/tests/src/signed_integers/signed_i8_twos_complement/src/main.sw b/tests/src/signed_integers/signed_i8_twos_complement/src/main.sw deleted file mode 100644 index 2e4bde0c..00000000 --- a/tests/src/signed_integers/signed_i8_twos_complement/src/main.sw +++ /dev/null @@ -1,29 +0,0 @@ -script; - -use sway_libs::signed_integers::i8::I8; - -fn main() -> bool { - let one = I8::from(1u8); - let mut res = one + I8::from(1u8); - assert(res.twos_complement() == I8::from(2u8)); - - res = I8::from(10u8); - assert(res.twos_complement() == I8::from(10u8)); - - res = I8::neg_from(5); - assert(res.twos_complement().underlying() + res.underlying() == u8::max() + 1); - - res = I8::neg_from(27u8); - assert(res.twos_complement().underlying() + res.underlying() == u8::max() + 1); - - res = I8::neg_from(110u8); - assert(res.twos_complement().underlying() + res.underlying() == u8::max() + 1); - - res = I8::neg_from(93u8); - assert(res.twos_complement().underlying() + res.underlying() == u8::max() + 1); - - res = I8::neg_from(78u8); - assert(res.twos_complement().underlying() + res.underlying() == u8::max() + 1); - - true -} diff --git a/tests/src/signed_integers/signed_i8_twos_complement/tests/mod.rs b/tests/src/signed_integers/signed_i8_twos_complement/tests/mod.rs deleted file mode 100644 index 1381185a..00000000 --- a/tests/src/signed_integers/signed_i8_twos_complement/tests/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -use fuels::prelude::{abigen, launch_provider_and_get_wallet}; - -abigen!(Script( - name = "Testi8TwosComplement", - abi = - "src/signed_integers/signed_i8_twos_complement/out/release/i8_twos_complement_test-abi.json" -),); - -mod success { - - use super::*; - - #[tokio::test] - async fn runs_i8_twos_complement_test_script() { - let path_to_bin = - "src/signed_integers/signed_i8_twos_complement/out/release/i8_twos_complement_test.bin"; - let wallet = launch_provider_and_get_wallet().await.unwrap(); - - let instance = Testi8TwosComplement::new(wallet, path_to_bin); - - let _result = instance.main().call().await; - } -} diff --git a/tests/src/fixed_point/ifp64_exp_test/.gitignore b/tests/src/signed_integers/signed_i8_wrapping_neg/.gitignore similarity index 100% rename from tests/src/fixed_point/ifp64_exp_test/.gitignore rename to tests/src/signed_integers/signed_i8_wrapping_neg/.gitignore diff --git a/tests/src/fixed_point/ifp256_div_test/Forc.toml b/tests/src/signed_integers/signed_i8_wrapping_neg/Forc.toml similarity index 83% rename from tests/src/fixed_point/ifp256_div_test/Forc.toml rename to tests/src/signed_integers/signed_i8_wrapping_neg/Forc.toml index 09c679a7..1ac93c5d 100644 --- a/tests/src/fixed_point/ifp256_div_test/Forc.toml +++ b/tests/src/signed_integers/signed_i8_wrapping_neg/Forc.toml @@ -2,7 +2,7 @@ authors = ["Fuel Labs "] entry = "main.sw" license = "Apache-2.0" -name = "ifp256_div_test" +name = "i8_wrapping_neg_test" [dependencies] sway_libs = { path = "../../../../libs" } diff --git a/tests/src/fixed_point/ufp32_div_test/mod.rs b/tests/src/signed_integers/signed_i8_wrapping_neg/mod.rs similarity index 100% rename from tests/src/fixed_point/ufp32_div_test/mod.rs rename to tests/src/signed_integers/signed_i8_wrapping_neg/mod.rs diff --git a/tests/src/signed_integers/signed_i8_wrapping_neg/src/main.sw b/tests/src/signed_integers/signed_i8_wrapping_neg/src/main.sw new file mode 100644 index 00000000..5282dcd6 --- /dev/null +++ b/tests/src/signed_integers/signed_i8_wrapping_neg/src/main.sw @@ -0,0 +1,60 @@ +script; + +use sway_libs::signed_integers::i8::I8; + +fn main() -> bool { + let one = I8::try_from(1u8).unwrap(); + let neg_one = I8::neg_try_from(1u8).unwrap(); + + let two = I8::try_from(2u8).unwrap(); + let neg_two = I8::neg_try_from(2u8).unwrap(); + + let ten = I8::try_from(10u8).unwrap(); + let neg_ten = I8::neg_try_from(10u8).unwrap(); + + let twenty_seven = I8::try_from(27u8).unwrap(); + let neg_twenty_seven = I8::neg_try_from(27u8).unwrap(); + + let ninty_three = I8::try_from(93u8).unwrap(); + let neg_ninty_three = I8::neg_try_from(93u8).unwrap(); + + let zero = I8::try_from(0u8).unwrap(); + let max = I8::max(); + let min = I8::min(); + let neg_min_plus_one = I8::min() + I8::try_from(1u8).unwrap(); + + let res1 = one.wrapping_neg(); + let res2 = neg_one.wrapping_neg(); + assert(res1 == neg_one); + assert(res2 == one); + + let res3 = two.wrapping_neg(); + let res4 = neg_two.wrapping_neg(); + assert(res3 == neg_two); + assert(res4 == two); + + let res5 = ten.wrapping_neg(); + let res6 = neg_ten.wrapping_neg(); + assert(res5 == neg_ten); + assert(res6 == ten); + + let res7 = twenty_seven.wrapping_neg(); + let res8 = neg_twenty_seven.wrapping_neg(); + assert(res7 == neg_twenty_seven); + assert(res8 == twenty_seven); + + let res9 = ninty_three.wrapping_neg(); + let res10 = neg_ninty_three.wrapping_neg(); + assert(res9 == neg_ninty_three); + assert(res10 == ninty_three); + + let res11 = zero.wrapping_neg(); + let res12 = max.wrapping_neg(); + let res13 = min.wrapping_neg(); + + assert(res11 == zero); + assert(res12 == neg_min_plus_one); + assert(res13 == min); + + true +} diff --git a/tests/src/signed_integers/signed_i8_wrapping_neg/tests/mod.rs b/tests/src/signed_integers/signed_i8_wrapping_neg/tests/mod.rs new file mode 100644 index 00000000..4046bb3a --- /dev/null +++ b/tests/src/signed_integers/signed_i8_wrapping_neg/tests/mod.rs @@ -0,0 +1,22 @@ +use fuels::prelude::{abigen, launch_provider_and_get_wallet}; + +abigen!(Script( + name = "Testi8WrappingNeg", + abi = "src/signed_integers/signed_i8_wrapping_neg/out/release/i8_wrapping_neg_test-abi.json" +),); + +mod success { + + use super::*; + + #[tokio::test] + async fn runs_signed_i8_wrapping_neg_test_script() { + let path_to_bin = + "src/signed_integers/signed_i8_wrapping_neg/out/release/i8_wrapping_neg_test.bin"; + let wallet = launch_provider_and_get_wallet().await.unwrap(); + + let instance = Testi8WrappingNeg::new(wallet, path_to_bin); + + let _result = instance.main().call().await; + } +} diff --git a/tests/src/upgradability/Forc.toml b/tests/src/upgradability/Forc.toml new file mode 100644 index 00000000..d495ef19 --- /dev/null +++ b/tests/src/upgradability/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "upgradability_test" + +[dependencies] +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.1" } +sway_libs = { path = "../../../libs" } diff --git a/tests/src/fixed_point/ifp128_div_test/mod.rs b/tests/src/upgradability/mod.rs similarity index 100% rename from tests/src/fixed_point/ifp128_div_test/mod.rs rename to tests/src/upgradability/mod.rs diff --git a/tests/src/upgradability/src/main.sw b/tests/src/upgradability/src/main.sw new file mode 100644 index 00000000..275fb8ad --- /dev/null +++ b/tests/src/upgradability/src/main.sw @@ -0,0 +1,71 @@ +contract; + +use sway_libs::upgradability::{ + _proxy_owner, + _proxy_target, + _set_proxy_owner, + _set_proxy_target, + only_proxy_owner, +}; +use standards::{src14::{SRC14, SRC14Extension}, src5::State}; + +configurable { + INITIAL_TARGET: Option = None, + INITIAL_OWNER: State = State::Uninitialized, +} + +#[namespace(SRC14)] +storage { + // target is at sha256("storage_SRC14_0") + target: Option = None, + proxy_owner: State = State::Uninitialized, +} + +abi UpgradableTest { + #[storage(read)] + fn only_proxy_owner(); + + #[storage(write)] + fn set_proxy_owner(new_proxy_owner: State); + + #[storage(write)] + fn initialize_proxy(); +} + +impl SRC14 for Contract { + #[storage(read, write)] + fn set_proxy_target(new_target: ContractId) { + _set_proxy_target(new_target); + } + + #[storage(read)] + fn proxy_target() -> Option { + _proxy_target() + } +} + +impl SRC14Extension for Contract { + #[storage(read)] + fn proxy_owner() -> State { + _proxy_owner(storage.proxy_owner) + } +} + +impl UpgradableTest for Contract { + #[storage(read)] + fn only_proxy_owner() { + only_proxy_owner(storage.proxy_owner); + } + + #[storage(write)] + fn set_proxy_owner(new_proxy_owner: State) { + _set_proxy_owner(new_proxy_owner, storage.proxy_owner); + } + + // Used to immediately set the storage variables as the configured constants + #[storage(write)] + fn initialize_proxy() { + storage.target.write(INITIAL_TARGET); + storage.proxy_owner.write(INITIAL_OWNER); + } +} diff --git a/tests/src/upgradability/tests/functions/mod.rs b/tests/src/upgradability/tests/functions/mod.rs new file mode 100644 index 00000000..daf01fb9 --- /dev/null +++ b/tests/src/upgradability/tests/functions/mod.rs @@ -0,0 +1,5 @@ +mod only_proxy_owner; +mod proxy_owner; +mod proxy_target; +mod set_proxy_owner; +mod set_proxy_target; diff --git a/tests/src/upgradability/tests/functions/only_proxy_owner.rs b/tests/src/upgradability/tests/functions/only_proxy_owner.rs new file mode 100644 index 00000000..01a00e52 --- /dev/null +++ b/tests/src/upgradability/tests/functions/only_proxy_owner.rs @@ -0,0 +1,55 @@ +use crate::upgradability::tests::utils::{ + abi_calls::{only_proxy_owner, set_proxy_owner}, + test_helpers::setup, + State, +}; + +mod success { + + use super::*; + + #[tokio::test] + async fn only_owner_may_call() { + let (_deployer, owner1, _owner2) = setup().await; + + only_proxy_owner(&owner1.contract).await; + } + + #[tokio::test] + async fn only_owner_after_transfer() { + let (_deployer, owner1, owner2) = setup().await; + + only_proxy_owner(&owner1.contract).await; + + set_proxy_owner( + &owner1.contract, + State::Initialized(owner2.wallet.address().into()), + ) + .await; + + only_proxy_owner(&owner2.contract).await; + } +} + +mod reverts { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "NotOwner")] + async fn when_not_owner() { + let (_deployer, _owner1, owner2) = setup().await; + + only_proxy_owner(&owner2.contract).await; + } + + #[tokio::test] + #[should_panic(expected = "NotOwner")] + async fn when_no_owner() { + let (_deployer, owner1, _owner2) = setup().await; + + set_proxy_owner(&owner1.contract, State::Revoked).await; + + only_proxy_owner(&owner1.contract).await; + } +} diff --git a/tests/src/upgradability/tests/functions/proxy_owner.rs b/tests/src/upgradability/tests/functions/proxy_owner.rs new file mode 100644 index 00000000..59eadb63 --- /dev/null +++ b/tests/src/upgradability/tests/functions/proxy_owner.rs @@ -0,0 +1,27 @@ +mod success { + + use crate::upgradability::tests::utils::{ + abi_calls::{proxy_owner, set_proxy_owner}, + test_helpers::setup, + State, + }; + + #[tokio::test] + async fn returns_initialized_owner() { + let (_deployer, owner1, _owner2) = setup().await; + + assert_eq!( + proxy_owner(&owner1.contract).await.value, + State::Initialized(owner1.wallet.address().into()) + ); + } + + #[tokio::test] + async fn returns_owner_on_state_change() { + let (_deployer, owner1, _owner2) = setup().await; + + set_proxy_owner(&owner1.contract, State::Revoked).await; + + assert_eq!(proxy_owner(&owner1.contract).await.value, State::Revoked); + } +} diff --git a/tests/src/upgradability/tests/functions/proxy_target.rs b/tests/src/upgradability/tests/functions/proxy_target.rs new file mode 100644 index 00000000..d0a51d3b --- /dev/null +++ b/tests/src/upgradability/tests/functions/proxy_target.rs @@ -0,0 +1,30 @@ +mod success { + + use crate::upgradability::tests::utils::{ + abi_calls::{proxy_target, set_proxy_target}, + test_helpers::{setup, SECOND_TARGET}, + }; + use fuels::types::ContractId; + + #[tokio::test] + async fn returns_initialized_target() { + let (_deployer, owner1, _owner2) = setup().await; + + assert_eq!( + proxy_target(&owner1.contract).await.value, + Some(ContractId::zeroed()) + ); + } + + #[tokio::test] + async fn returns_target_on_state_change() { + let (_deployer, owner1, _owner2) = setup().await; + + set_proxy_target(&owner1.contract, SECOND_TARGET).await; + + assert_eq!( + proxy_target(&owner1.contract).await.value, + Some(SECOND_TARGET) + ); + } +} diff --git a/tests/src/upgradability/tests/functions/set_proxy_owner.rs b/tests/src/upgradability/tests/functions/set_proxy_owner.rs new file mode 100644 index 00000000..f5508e93 --- /dev/null +++ b/tests/src/upgradability/tests/functions/set_proxy_owner.rs @@ -0,0 +1,70 @@ +use crate::upgradability::tests::utils::{ + abi_calls::{proxy_owner, set_proxy_owner}, + test_helpers::setup, + State, +}; + +mod success { + + use super::*; + + #[tokio::test] + async fn sets_a_new_owner() { + let (_deployer, owner1, owner2) = setup().await; + + assert_eq!( + proxy_owner(&owner1.contract).await.value, + State::Initialized(owner1.wallet.address().into()) + ); + + set_proxy_owner( + &owner1.contract, + State::Initialized(owner2.wallet.address().into()), + ) + .await; + + assert_eq!( + proxy_owner(&owner1.contract).await.value, + State::Initialized(owner2.wallet.address().into()) + ); + } + + #[tokio::test] + async fn revokes_ownership() { + let (_deployer, owner1, _owner2) = setup().await; + + assert_eq!( + proxy_owner(&owner1.contract).await.value, + State::Initialized(owner1.wallet.address().into()) + ); + + set_proxy_owner(&owner1.contract, State::Revoked).await; + + assert_eq!(proxy_owner(&owner1.contract).await.value, State::Revoked); + } +} + +mod reverts { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "NotOwner")] + async fn when_called_by_non_owner() { + let (_deployer, _owner1, owner2) = setup().await; + + set_proxy_owner( + &owner2.contract, + State::Initialized(owner2.wallet.address().into()), + ) + .await; + } + + #[tokio::test] + #[should_panic(expected = "CannotUninitialize")] + async fn when_setting_the_new_state_to_uninitialized() { + let (_deployer, owner1, _owner2) = setup().await; + + set_proxy_owner(&owner1.contract, State::Uninitialized).await; + } +} diff --git a/tests/src/upgradability/tests/functions/set_proxy_target.rs b/tests/src/upgradability/tests/functions/set_proxy_target.rs new file mode 100644 index 00000000..de165785 --- /dev/null +++ b/tests/src/upgradability/tests/functions/set_proxy_target.rs @@ -0,0 +1,24 @@ +mod success { + + use crate::upgradability::tests::utils::{ + abi_calls::{proxy_target, set_proxy_target}, + test_helpers::{setup, INITIAL_TARGET, SECOND_TARGET}, + }; + + #[tokio::test] + async fn sets_a_new_target() { + let (_deployer, owner1, _owner2) = setup().await; + + assert_eq!( + proxy_target(&owner1.contract).await.value, + Some(INITIAL_TARGET) + ); + + set_proxy_target(&owner1.contract, SECOND_TARGET).await; + + assert_eq!( + proxy_target(&owner1.contract).await.value, + Some(SECOND_TARGET) + ); + } +} diff --git a/tests/src/upgradability/tests/mod.rs b/tests/src/upgradability/tests/mod.rs new file mode 100644 index 00000000..39c93631 --- /dev/null +++ b/tests/src/upgradability/tests/mod.rs @@ -0,0 +1,2 @@ +mod functions; +mod utils; diff --git a/tests/src/upgradability/tests/utils/mod.rs b/tests/src/upgradability/tests/utils/mod.rs new file mode 100644 index 00000000..4b52c7fa --- /dev/null +++ b/tests/src/upgradability/tests/utils/mod.rs @@ -0,0 +1,142 @@ +use fuels::{ + prelude::{ + abigen, launch_custom_provider_and_get_wallets, Contract, ContractId, LoadConfiguration, + StorageConfiguration, TxPolicies, WalletUnlocked, WalletsConfig, + }, + programs::call_response::FuelCallResponse, +}; + +// Load abi from json +abigen!(Contract( + name = "UpgradabilityLib", + abi = "src/upgradability/out/release/upgradability_test-abi.json" +)); + +pub struct Metadata { + pub contract: UpgradabilityLib, + pub wallet: WalletUnlocked, +} + +pub mod abi_calls { + + use super::*; + + pub async fn set_proxy_target( + contract: &UpgradabilityLib, + new_target: ContractId, + ) -> FuelCallResponse<()> { + contract + .methods() + .set_proxy_target(new_target) + .call() + .await + .unwrap() + } + + pub async fn proxy_target( + contract: &UpgradabilityLib, + ) -> FuelCallResponse> { + contract.methods().proxy_target().call().await.unwrap() + } + + pub async fn proxy_owner( + contract: &UpgradabilityLib, + ) -> FuelCallResponse { + contract.methods().proxy_owner().call().await.unwrap() + } + + pub async fn only_proxy_owner( + contract: &UpgradabilityLib, + ) -> FuelCallResponse<()> { + contract.methods().only_proxy_owner().call().await.unwrap() + } + + pub async fn set_proxy_owner( + contract: &UpgradabilityLib, + new_proxy_owner: State, + ) -> FuelCallResponse<()> { + contract + .methods() + .set_proxy_owner(new_proxy_owner) + .call() + .await + .unwrap() + } + + pub async fn initialize_proxy( + contract: &UpgradabilityLib, + ) -> FuelCallResponse<()> { + contract.methods().initialize_proxy().call().await.unwrap() + } +} + +pub mod test_helpers { + + use super::*; + use abi_calls::initialize_proxy; + + pub const INITIAL_TARGET: ContractId = ContractId::zeroed(); + pub const SECOND_TARGET: ContractId = ContractId::new([1u8; 32]); + + pub async fn setup() -> (Metadata, Metadata, Metadata) { + let num_wallets = 3; + let coins_per_wallet = 1; + let coin_amount = 1_000_000; + let mut wallets = launch_custom_provider_and_get_wallets( + WalletsConfig::new(Some(num_wallets), Some(coins_per_wallet), Some(coin_amount)), + None, + None, + ) + .await + .unwrap(); + + // Get the wallets from that provider + let wallet1 = wallets.pop().unwrap(); + let wallet2 = wallets.pop().unwrap(); + let wallet3 = wallets.pop().unwrap(); + + let storage_configuration = StorageConfiguration::default() + .add_slot_overrides_from_file( + "src/upgradability/out/release/upgradability_test-storage_slots.json", + ) + .unwrap(); + + let configurables = UpgradabilityLibConfigurables::default() + .with_INITIAL_TARGET(Some(INITIAL_TARGET)) + .unwrap() + .with_INITIAL_OWNER(State::Initialized(wallet2.address().into())) + .unwrap(); + + let configuration = LoadConfiguration::default() + .with_storage_configuration(storage_configuration) + .with_configurables(configurables); + + let id = Contract::load_from( + "src/upgradability/out/release/upgradability_test.bin", + configuration, + ) + .unwrap() + .deploy(&wallet1, TxPolicies::default()) + .await + .unwrap(); + + let deploy_wallet = Metadata { + contract: UpgradabilityLib::new(id.clone(), wallet1.clone()), + wallet: wallet1.clone(), + }; + + let owner1 = Metadata { + contract: UpgradabilityLib::new(id.clone(), wallet2.clone()), + wallet: wallet2.clone(), + }; + + let owner2 = Metadata { + contract: UpgradabilityLib::new(id.clone(), wallet3.clone()), + wallet: wallet3.clone(), + }; + + initialize_proxy(&deploy_wallet.contract).await; + + (deploy_wallet, owner1, owner2) + } +}