forked from FuelLabs/sway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
#[payable]
annotation to ABI methods (FuelLabs#3450)
## Description The lack of this annotation implies the method is non-payable. When calling an ABI method that is non-payable, the compiler must emit an error if the amount of coins to forward is not guaranteed to be zero. The compiler also emits an error if the method signature and the method implementation have different `#[payable]` annotations. ## Assumptions Currently, the analysis of non-zero coins is very simple and only checks if the special `coins:` contract call parameter is the zero `u64` literal directly or can be reached through a chain of variable/constant definitions. ## Tests - [x] Must fail when scripts call non-payable methods with non-zero coins as a literal - [x] Must fail when scripts call non-payable methods with non-zero coins as a constant - [x] Must fail when scripts call non-payable methods with non-zero coins as a variable definition - [x] Must fail when contracts call non-payable methods with non-zero coins - [x] Must fail when there is an extra `#[payable]` annotation in method implementation (not mentioned in its signature) - [x] Must fail when the `#[payable]` annotation in method implementation is missing (but mentioned in its signature) close FuelLabs#1608 ## TODOs - [x] Fix `#[payable]` annotations for the standard library - [x] Fix the empty parens issue for formatting attributes: FuelLabs#3451 - [x] Parser should allow us write annotations like so: `#[storage(read, write), payable]`: FuelLabs#3452 - [x] Refactor `#[payable]` annotations in this PR in the style above - [x] Add more complex formatter unit tests with `payable` - [x] As pointed out by @mohammadfawaz, the SDK can bypass payable annotations and one option would be to add function attributes to the [JSON ABI schema](https://fuellabs.github.io/fuel-specs/master/protocol/abi/json_abi_format.html) and process it in the SDK (see these issues: FuelLabs/fuel-specs#446 and FuelLabs/fuels-rs#742) - [x] Bump `fuels-rs`'s version Co-authored-by: Mohammad Fawaz <[email protected]>
- Loading branch information
1 parent
02d9b3d
commit 211667c
Showing
282 changed files
with
1,683 additions
and
19 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
library other_contract; | ||
|
||
abi OtherContract { | ||
#[payable] | ||
fn external_call(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use crate::{ | ||
language::ty::{self, TyExpression}, | ||
Namespace, | ||
}; | ||
|
||
// This analysis checks if an expression is known statically to evaluate | ||
// to a non-zero value at runtime. | ||
// It's intended to be used in the payability analysis to check if a non-payable | ||
// method gets called with a non-zero amount of `coins` | ||
pub fn possibly_nonzero_u64_expression(namespace: &Namespace, expr: &TyExpression) -> bool { | ||
use ty::TyExpressionVariant::*; | ||
match &expr.expression { | ||
Literal(crate::language::Literal::U64(value)) => *value != 0, | ||
// not a u64 literal, hence we return true to be on the safe side | ||
Literal(_) => true, | ||
VariableExpression { name, .. } => { | ||
match namespace.resolve_symbol(name).value { | ||
Some(ty_decl) => { | ||
match ty_decl { | ||
ty::TyDeclaration::VariableDeclaration(var_decl) => { | ||
possibly_nonzero_u64_expression(namespace, &var_decl.body) | ||
} | ||
ty::TyDeclaration::ConstantDeclaration(decl_id) => { | ||
match crate::declaration_engine::de_get_constant( | ||
decl_id.clone(), | ||
&expr.span, | ||
) { | ||
Ok(const_decl) => { | ||
possibly_nonzero_u64_expression(namespace, &const_decl.value) | ||
} | ||
Err(_) => true, | ||
} | ||
} | ||
_ => true, // impossible cases, true is a safer option here | ||
} | ||
} | ||
None => { | ||
// Unknown variable, but it's not possible in a well-typed expression | ||
// returning true here just to be on the safe side | ||
true | ||
} | ||
} | ||
} | ||
// We do not treat complex expressions at the moment: the rational for this | ||
// is that the `coins` contract call parameter is usually a literal, a variable, | ||
// or a constant. | ||
// Since we don't analyze the following types of expressions, we just assume | ||
// those result in non-zero amount of coins | ||
FunctionApplication { .. } | ||
| ArrayIndex { .. } | ||
| CodeBlock(_) | ||
| IfExp { .. } | ||
| AsmExpression { .. } | ||
| StructFieldAccess { .. } | ||
| TupleElemAccess { .. } | ||
| StorageAccess(_) | ||
| WhileLoop { .. } => true, | ||
// The following expression variants are unreachable, because of the type system | ||
// but we still consider these as non-zero to be on the safe side | ||
LazyOperator { .. } | ||
| Tuple { .. } | ||
| Array { .. } | ||
| StructExpression { .. } | ||
| FunctionParameter | ||
| EnumInstantiation { .. } | ||
| AbiCast { .. } | ||
| IntrinsicFunction(_) | ||
| AbiName(_) | ||
| UnsafeDowncast { .. } | ||
| EnumTag { .. } | ||
| Break | ||
| Continue | ||
| Reassignment(_) | ||
| Return(_) | ||
| StorageReassignment(_) => true, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.