diff --git a/README.md b/README.md index 06b6f9f..21d10a9 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,20 @@ Yul recompiler to LLVM, targetting RISC-V on [PolkaVM](https://github.com/koute/ Check the [docs](https://paritytech.github.io/revive/) or visit [contracts.polkadot.io](https://docs.polkadot.com/develop/smart-contracts/) to learn more about `revive` and contracts on Polkadot! -## Status - -This is experimental software in active development and not ready just yet for production usage. Please do report any compiler related issues or missing features that are [not yet known to us](https://contracts.polkadot.io/known_issues/) here. - Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1). +> [!WARNING] +> +> Solidity on PVM is running on the `pallet-revive` runtime. This introduces **observable semantic differences** in comparison with the EVM. +> +> Study the [differences](https://paritytech.github.io/revive/user_guide/differences.html) section carefully. **Ignoring these differences may lead to defunct contracts.** +> +> Notable examples: +> - The 63/64 gas rule isn't implemented in the pallet (introduces potential DoS vector when calling other contracts) +> - Contract instantiation works differently (by hash instead of by code) +> - The gas model implemented by `pallet-revive` differs from Ethereum +> - The heap size is fixed instead of gas-metered and there's a fixed amount of stack size (contracts working fine on EVM may trap on PVM) + ## Installation Building Solidity contracts for PolkaVM requires installing the following two compilers: diff --git a/book/src/user_guide/differences.md b/book/src/user_guide/differences.md index 1835304..917be1d 100644 --- a/book/src/user_guide/differences.md +++ b/book/src/user_guide/differences.md @@ -18,6 +18,10 @@ Therefore, in EVM terminology, the deploy code equals the runtime code. We are aware of the following differences in the translation of Solidity code. +### The `63/64` gas rule + +`pallet-revive` **doesn't apply the `63/64` gas rule**. We strongly advice to change any code calling untrusted contracts to supply a limited amount of gas only! + ### `address.creationCode` This returns the bytecode keccak256 hash instead. @@ -28,7 +32,7 @@ The below list contains noteworthy differences in the translation of YUL functio > [!NOTE] > -> Many functions receive memory buffer offset pointer or size arguments. Since the PVM pointer size is 32 bit, supplying memory offset or buffer size values above `2^32-1` will trap the contract immediately. +> Many functions receive memory buffer offset pointer or size arguments. The PVM pointer size is 32 bit, supplying memory offset or buffer size values above `2^32-1` may lead to `OutOfGas` errors trap contract execution. The `solc` compiler ought to always emit valid memory references, so Solidity dApp authors don't need to worry about this unless they deal with low level `assembly` code. @@ -43,6 +47,10 @@ In general, revive preserves the memory layout, meaning low level memory operati In the constructor code, the offset is ignored and this always returns `0`. +> [!WARNING] +> +> `pallet-revive` restricts the calldata size (to 128kb at the time of writing). + ### `codecopy` Only supported in constructor code. @@ -70,6 +78,10 @@ Returns the contract hash. Returns the contract hash size (constant value of `32`). +### `revert`, `return` + +`pallet-revive` restricts the returndata size (to 128kb at the time of writing). + ### `prevrandao`, `difficulty` Translates to a constant value of `2500000000000000`. diff --git a/book/src/welcome.md b/book/src/welcome.md index 0314d49..df44269 100644 --- a/book/src/welcome.md +++ b/book/src/welcome.md @@ -2,6 +2,18 @@ Hello and a warm welcome to the `revive` Solidity compiler book! +> [!WARNING] +> +> Solidity on PVM is running on the `pallet-revive` runtime. This introduces **observable semantic differences** in comparison with the EVM. +> +> Study the [differences](https://paritytech.github.io/revive/user_guide/differences.html) section carefully. **Ignoring these differences may lead to defunct contracts.** +> +> Notable examples: +> - The 63/64 gas rule isn't implemented in the pallet (introduces potential DoS vector when calling other contracts) +> - Contract instantiation works differently (by hash instead of by code) +> - The gas model implemented by `pallet-revive` differs from Ethereum +> - The heap size is fixed instead of gas-metered and there's a fixed amount of stack size (contracts working fine on EVM may trap on PVM) + ## Target audience - **Solidity dApp developers** should read the [user guide](./user_guide.md). Solidity on PolkaVM introduces important differences to EVM which should be well understood. diff --git a/crates/integration/contracts/RevertDataOob.sol b/crates/integration/contracts/RevertDataOob.sol new file mode 100644 index 0000000..ab6eb92 --- /dev/null +++ b/crates/integration/contracts/RevertDataOob.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.8.0; + +/* runner.json +{ + "differential": true, + "actions": [ + { + "Instantiate": { + "code": { + "Solidity": { + "contract": "RevertDataOob" + } + } + } + }, + { + "Call": { + "dest": { + "Instantiated": 0 + }, + "data": "eb8ac921000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff" + } + }, + { + "Call": { + "dest": { + "Instantiated": 0 + }, + "data": "eb8ac92100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000" + } + } + ] +} +*/ + +contract RevertDataOob { + function test(uint256 offset, uint256 len) external { + assembly { + mstore(0, 0xcc572cf9) + mstore(32, offset) + mstore(64, len) + let stipend := mul(div(gas(), 64), 63) // On EVM this isn't necessary + let success := call(stipend, address(), 0, 28, 68, 0, 0) + mstore(0, 0xdeadbeef) + return(0, 32) + } + } + + function main(uint256 offset, uint256 len) external pure { + assembly { + mstore(0x40, 0) + revert(offset, len) + } + } +} diff --git a/crates/integration/src/tests.rs b/crates/integration/src/tests.rs index ee2760f..24144e8 100644 --- a/crates/integration/src/tests.rs +++ b/crates/integration/src/tests.rs @@ -44,6 +44,7 @@ test_spec!(create, "CreateB", "Create.sol"); test_spec!(call, "Caller", "Call.sol"); test_spec!(balance, "Balance", "Balance.sol"); test_spec!(return_data_oob, "ReturnDataOob", "ReturnDataOob.sol"); +test_spec!(revert_data_oob, "RevertDataOob", "RevertDataOob.sol"); test_spec!(immutables, "Immutables", "Immutables.sol"); test_spec!(transaction, "Transaction", "Transaction.sol"); test_spec!(block_hash, "BlockHash", "BlockHash.sol"); diff --git a/docs/404.html b/docs/404.html index 09ec9ea..ef90f2f 100644 --- a/docs/404.html +++ b/docs/404.html @@ -36,7 +36,7 @@ const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "searchindex-c7304031.js"; diff --git a/docs/developer_guide.html b/docs/developer_guide.html index 470efad..5aa65f4 100644 --- a/docs/developer_guide.html +++ b/docs/developer_guide.html @@ -35,7 +35,7 @@ const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "searchindex-c7304031.js"; diff --git a/docs/developer_guide/architecture.html b/docs/developer_guide/architecture.html index 02d4489..e994ce1 100644 --- a/docs/developer_guide/architecture.html +++ b/docs/developer_guide/architecture.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/developer_guide/contributing.html b/docs/developer_guide/contributing.html index 33a68ff..d3d8bc1 100644 --- a/docs/developer_guide/contributing.html +++ b/docs/developer_guide/contributing.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/developer_guide/cross_compilation.html b/docs/developer_guide/cross_compilation.html index 466f4ca..bfe0fac 100644 --- a/docs/developer_guide/cross_compilation.html +++ b/docs/developer_guide/cross_compilation.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/developer_guide/target.html b/docs/developer_guide/target.html index 0d61ebb..e68cb14 100644 --- a/docs/developer_guide/target.html +++ b/docs/developer_guide/target.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/developer_guide/testing.html b/docs/developer_guide/testing.html index 84c780a..8bc8437 100644 --- a/docs/developer_guide/testing.html +++ b/docs/developer_guide/testing.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/faq.html b/docs/faq.html index 8efd395..abf2285 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -35,7 +35,7 @@ const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "searchindex-c7304031.js"; diff --git a/docs/index.html b/docs/index.html index 27694fd..4fed031 100644 --- a/docs/index.html +++ b/docs/index.html @@ -35,7 +35,7 @@ const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "searchindex-c7304031.js"; @@ -176,6 +176,18 @@

Welcome

Hello and a warm welcome to the revive Solidity compiler book!

+
+

Warning

+

Solidity on PVM is running on the pallet-revive runtime. This introduces observable semantic differences in comparison with the EVM.

+

Study the differences section carefully. Ignoring these differences may lead to defunct contracts.

+

Notable examples:

+ +

Target audience

calldataload, calldatacopy

In the constructor code, the offset is ignored and this always returns 0.

+
+

Warning

+

pallet-revive restricts the calldata size (to 128kb at the time of writing).

+

codecopy

Only supported in constructor code.

create, create2

@@ -225,6 +231,8 @@ Thus, revive is able to supply the expected code hash and construct

Returns the contract hash.

datasize

Returns the contract hash size (constant value of 32).

+

revert, return

+

pallet-revive restricts the returndata size (to 128kb at the time of writing).

prevrandao, difficulty

Translates to a constant value of 2500000000000000.

pc, extcodecopy

diff --git a/docs/user_guide/installation.html b/docs/user_guide/installation.html index c98d52d..e7d21b9 100644 --- a/docs/user_guide/installation.html +++ b/docs/user_guide/installation.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/user_guide/js.html b/docs/user_guide/js.html index cf9bdd6..060381b 100644 --- a/docs/user_guide/js.html +++ b/docs/user_guide/js.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/user_guide/rust_libraries.html b/docs/user_guide/rust_libraries.html index 9459149..58bd0f9 100644 --- a/docs/user_guide/rust_libraries.html +++ b/docs/user_guide/rust_libraries.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/user_guide/std_json.html b/docs/user_guide/std_json.html index 7424da0..259a04c 100644 --- a/docs/user_guide/std_json.html +++ b/docs/user_guide/std_json.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/user_guide/tooling.html b/docs/user_guide/tooling.html index 830c5cc..5012568 100644 --- a/docs/user_guide/tooling.html +++ b/docs/user_guide/tooling.html @@ -35,7 +35,7 @@ const path_to_root = "../"; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "../searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "../searchindex-c7304031.js"; diff --git a/docs/welcome.html b/docs/welcome.html index 27694fd..4fed031 100644 --- a/docs/welcome.html +++ b/docs/welcome.html @@ -35,7 +35,7 @@ const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; - window.path_to_searchindex_js = "searchindex-4ae832c1.js"; + window.path_to_searchindex_js = "searchindex-c7304031.js"; @@ -176,6 +176,18 @@

Welcome

Hello and a warm welcome to the revive Solidity compiler book!

+
+

Warning

+

Solidity on PVM is running on the pallet-revive runtime. This introduces observable semantic differences in comparison with the EVM.

+

Study the differences section carefully. Ignoring these differences may lead to defunct contracts.

+

Notable examples:

+
    +
  • The 63/64 gas rule isn’t implemented in the pallet (introduces potential DoS vector when calling other contracts)
  • +
  • Contract instantiation works differently (by hash instead of by code)
  • +
  • The gas model implemented by pallet-revive differs from Ethereum
  • +
  • The heap size is fixed instead of gas-metered and there’s a fixed amount of stack size (contracts working fine on EVM may trap on PVM)
  • +
+

Target audience