diff --git a/crates/abi/src/function.rs b/crates/abi/src/function.rs index 0fce7727d0..b7cc8a87cf 100644 --- a/crates/abi/src/function.rs +++ b/crates/abi/src/function.rs @@ -14,6 +14,36 @@ pub enum StateMutability { Payable, } +impl StateMutability { + pub fn decision(mut_self: Option, mut_ctx: Option) -> Self { + // Check ABI conformity + // https://github.com/ethereum/fe/issues/558 + // + // |none self | self | mut self | + // | none ctx | pure | view | payable/nonpayable | + // | ctx | view | view | payable/nonpayable | + // | mut ctx | payable/nopayable | view | payable/nonpayable | + // + // NOTE: we default payable for all method right now. But this should be resolve in the future. + + let state_mutability; + if mut_self.is_none() { + if mut_ctx.is_none() { + state_mutability = StateMutability::Pure; + } else if mut_ctx == Some(false) { + state_mutability = StateMutability::View + } else { + state_mutability = StateMutability::Payable; + } + } else if mut_self == Some(false) { + state_mutability = StateMutability::View; + } else { + state_mutability = StateMutability::Payable + } + state_mutability + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct AbiFunction { #[serde(rename = "type")] @@ -217,6 +247,42 @@ mod tests { #[test] fn test_state_mutability() { + assert_eq!(StateMutability::decision(None, None), StateMutability::Pure); + assert_eq!( + StateMutability::decision(None, Some(false)), + StateMutability::View + ); + assert_eq!( + StateMutability::decision(None, Some(true)), + StateMutability::Payable + ); + + assert_eq!( + StateMutability::decision(Some(false), None), + StateMutability::View + ); + assert_eq!( + StateMutability::decision(Some(false), Some(false)), + StateMutability::View + ); + assert_eq!( + StateMutability::decision(Some(false), Some(true)), + StateMutability::View + ); + + assert_eq!( + StateMutability::decision(Some(true), None), + StateMutability::Payable + ); + assert_eq!( + StateMutability::decision(Some(true), Some(false)), + StateMutability::Payable + ); + assert_eq!( + StateMutability::decision(Some(true), Some(true)), + StateMutability::Payable + ); + let pure_func = test_func(StateMutability::Pure); assert_eq!(pure_func.state_mutability, StateMutability::Pure); diff --git a/crates/codegen/src/db/queries/abi.rs b/crates/codegen/src/db/queries/abi.rs index 6a13b6c629..0fc4a82f9e 100644 --- a/crates/codegen/src/db/queries/abi.rs +++ b/crates/codegen/src/db/queries/abi.rs @@ -61,32 +61,13 @@ pub fn abi_function(db: &dyn CodegenDb, function: FunctionId) -> AbiFunction { let mut_self = sig.mut_self; let mut_ctx = sig.mut_ctx; - // Check ABI conformity - // https://github.com/ethereum/fe/issues/558 - // - // |none self | self | mut self | - // | none ctx | pure | view | payable/nonpayable | - // | ctx | view | view | payable/nonpayable | - // | mut ctx | payable/nopayable | view | payable/nonpayable | - // - // NOTE: we default payable for all method right now. But this should be resolve in the future. - - let state_mutability; - if mut_self.is_none() { - if mut_ctx.is_none() { - state_mutability = StateMutability::Pure; - } else if mut_ctx == Some(false) { - state_mutability = StateMutability::View - } else { - state_mutability = StateMutability::Payable; - } - } else if mut_self == Some(false) { - state_mutability = StateMutability::View; - } else { - state_mutability = StateMutability::Payable - } - - AbiFunction::new(func_type, name.to_string(), args, ret_ty, state_mutability) + AbiFunction::new( + func_type, + name.to_string(), + args, + ret_ty, + StateMutability::decision(mut_self, mut_ctx), + ) } pub fn abi_function_argument_maximum_size(db: &dyn CodegenDb, function: FunctionId) -> usize {