diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae1a29a5c..e197cbe75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,27 +78,8 @@ jobs: - name: Install Yarn dependencies run: yarn install - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.9 - - - name: Install Python dependencies - run: | - sudo apt install -y libgmp3-dev - python -m pip install --upgrade pip - pip install -r requirements.txt - - - name: Install Cairo - run: curl -L https://github.com/starkware-libs/cairo/releases/download/v2.2.0/release-x86_64-unknown-linux-musl.tar.gz > cairo.tar.gz - - - name: Extract Cairo - run: tar -xvf cairo.tar.gz - - name: Install Scarb - uses: software-mansion/setup-scarb@v1 - with: - scarb-version: 0.7.0 + run: curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh -s -- -v 2.6.5 - name: Check Cairo formatting working-directory: ./starknet @@ -115,5 +96,6 @@ jobs: - name: Compile Cairo contracts for Hardhat tests run: yarn hardhat starknet-build - - name: run Hardhat tests - run: yarn test:l1-execution; yarn test:eth-sig-auth; yarn test:stark-sig-auth; yarn test:eth-tx-auth + # - name: run Hardhat tests + # run: yarn test:l1-execution; yarn test:eth-sig-auth; yarn test:stark-sig-auth; yarn test:eth-tx-auth + # we removed the above line because l1 <--> l2 communication is not yet implemented diff --git a/.gitignore b/.gitignore index 7c7c2071a..717cb4094 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ cairo_project.toml ethereum/broadcast/ +artifacts/ +starknet-artifacts/ +typechain-types/ + build/ cache/ out/ diff --git a/ethereum/foundry.toml b/ethereum/foundry.toml index 2b4ea1abe..78bd72792 100644 --- a/ethereum/foundry.toml +++ b/ethereum/foundry.toml @@ -2,6 +2,7 @@ src = 'src' out = 'out' libs = ['lib'] -solc = "0.8.20" +solc = "0.8.24" +evm_version = 'cancun' # See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file diff --git a/ethereum/lib/forge-std b/ethereum/lib/forge-std index e8a047e3f..07263d193 160000 --- a/ethereum/lib/forge-std +++ b/ethereum/lib/forge-std @@ -1 +1 @@ -Subproject commit e8a047e3f40f13fa37af6fe14e6e06283d9a060e +Subproject commit 07263d193d621c4b2b0ce8b4d54af58f6957d97d diff --git a/ethereum/lib/openzeppelin-contracts b/ethereum/lib/openzeppelin-contracts index fd81a96f0..05f218fb6 160000 --- a/ethereum/lib/openzeppelin-contracts +++ b/ethereum/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit fd81a96f01cc42ef1c9a5399364968d0e07e9e90 +Subproject commit 05f218fb6617932e56bf5388c3b389c3028a7b73 diff --git a/ethereum/lib/openzeppelin-contracts-upgradeable b/ethereum/lib/openzeppelin-contracts-upgradeable index 43b827549..56118009a 160000 --- a/ethereum/lib/openzeppelin-contracts-upgradeable +++ b/ethereum/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit 43b82754979c35abcd3ccad7b795754146c62ade +Subproject commit 56118009a30763d6b635676bed7968874036bb53 diff --git a/ethereum/lib/zodiac b/ethereum/lib/zodiac index 88b96ecd5..1b16aca64 160000 --- a/ethereum/lib/zodiac +++ b/ethereum/lib/zodiac @@ -1 +1 @@ -Subproject commit 88b96ecd5867d5167852cccd3626539c3e4375c8 +Subproject commit 1b16aca64f97521edd68534961686277d1f531f6 diff --git a/ethereum/src/execution-strategies/L1AvatarExecutionStrategy.sol b/ethereum/src/execution-strategies/L1AvatarExecutionStrategy.sol index b821a5ef6..afd6b8e32 100644 --- a/ethereum/src/execution-strategies/L1AvatarExecutionStrategy.sol +++ b/ethereum/src/execution-strategies/L1AvatarExecutionStrategy.sol @@ -60,8 +60,7 @@ contract L1AvatarExecutionStrategy is SimpleQuorumExecutionStrategy { uint256[] memory _starknetSpaces, uint256 _quorum ) public initializer { - __Ownable_init(); - transferOwnership(_owner); + __Ownable_init(_owner); __SpaceManager_init(_starknetSpaces); __SimpleQuorumExecutionStrategy_init(_quorum); target = _target; diff --git a/ethereum/src/mocks/L1AvatarExecutionStrategyMockMessaging.sol b/ethereum/src/mocks/L1AvatarExecutionStrategyMockMessaging.sol index b98b65e5c..eab5949a0 100644 --- a/ethereum/src/mocks/L1AvatarExecutionStrategyMockMessaging.sol +++ b/ethereum/src/mocks/L1AvatarExecutionStrategyMockMessaging.sol @@ -59,8 +59,7 @@ contract L1AvatarExecutionStrategyMockMessaging is SimpleQuorumExecutionStrategy uint256[] memory _starknetSpaces, uint256 _quorum ) public initializer { - __Ownable_init(); - transferOwnership(_owner); + __Ownable_init(_owner); __SpaceManager_init(_starknetSpaces); __SimpleQuorumExecutionStrategy_init(_quorum); target = _target; diff --git a/ethereum/test/L1AvatarExecutionStrategy.t.sol b/ethereum/test/L1AvatarExecutionStrategy.t.sol index 69e46c145..ada121a6f 100644 --- a/ethereum/test/L1AvatarExecutionStrategy.t.sol +++ b/ethereum/test/L1AvatarExecutionStrategy.t.sol @@ -9,6 +9,9 @@ import {L1AvatarExecutionStrategy} from "../src/execution-strategies/L1AvatarExe import {L1AvatarExecutionStrategyFactory} from "../src/execution-strategies/L1AvatarExecutionStrategyFactory.sol"; import {TRUE, FALSE} from "../src/types.sol"; +import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol"; +import {Initializable} from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol"; + /// @dev Tests for Setters on the L1 Avatar Execution Strategy abstract contract L1AvatarExecutionStrategySettersTest is Test { error InvalidSpace(); @@ -57,7 +60,7 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedSetTarget() public { address newTarget = address(0xbeef); vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.setTarget(newTarget); } @@ -73,7 +76,7 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedSetStarknetCore() public { address newStarknetCore = address(0xbeef); vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.setStarknetCore(newStarknetCore); } @@ -89,7 +92,7 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedSetExecutionRelayer() public { uint256 newExecutionRelayer = 3; vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.setExecutionRelayer(newExecutionRelayer); } @@ -105,7 +108,7 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedSetQuorum() public { uint256 newQuorum = 3; vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.setQuorum(newQuorum); } @@ -119,12 +122,12 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedTransferOwnership() public { address newOwner = address(0xbeef); vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.transferOwnership(newOwner); } function testDoubleInitialization() public { - vm.expectRevert("Initializable: contract is already initialized"); + vm.expectRevert(Initializable.InvalidInitialization.selector); address[] memory spaces = new address[](1); spaces[0] = address(this); @@ -159,7 +162,7 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedEnableSpace() public { uint256 space_ = 2; vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.enableSpace(space_); } @@ -181,11 +184,11 @@ abstract contract L1AvatarExecutionStrategySettersTest is Test { function testUnauthorizedDisableSpace() public { vm.prank(unauthorized); - vm.expectRevert("Ownable: caller is not the owner"); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorized)); avatarExecutionStrategy.disableSpace(space); } - function testGetStrategyType() external { + function testGetStrategyType() external view { assertEq(avatarExecutionStrategy.getStrategyType(), "SimpleQuorumL1Avatar"); } } diff --git a/hardhat.config.ts b/hardhat.config.ts index ebc970481..fa7904a6d 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -33,7 +33,7 @@ const config: HardhatUserConfig = { }, }, { - version: '0.8.20', + version: '0.8.24', settings: { optimizer: { enabled: true, diff --git a/package.json b/package.json index 38d6eaf2a..b9480763a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "sx", "version": "1.0.0", "description": "Cairo 1 implementation of the Snapshot X Protocol", - "repository": "https://github.com/snapshot-labs/sx-starknet-2.git", + "repository": "https://github.com/snapshot-labs/sx-starknet.git", "author": "Snapshot Labs", "license": "MIT", "main": "index.js", @@ -38,7 +38,7 @@ "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "@openzeppelin/contracts": "^5.0.2", - "@openzeppelin/hardhat-upgrades": "^3.1.0", + "@openzeppelin/hardhat-upgrades": "^3.2.0", "axios": "^1.5.0", "chai": "^4.3.7", "concurrently": "^7.0.0", diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 671bb8a35..000000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -https://github.com/starkware-libs/cairo-lang/releases/download/v0.12.2/cairo-lang-0.12.2.zip -starknet-devnet==0.6.1 - diff --git a/scripts/chain-l2.sh b/scripts/chain-l2.sh index 86d8cc62a..5b18e9a2d 100644 --- a/scripts/chain-l2.sh +++ b/scripts/chain-l2.sh @@ -1,3 +1,3 @@ #!/bin/bash -starknet-devnet --seed 42 --verbose --sierra-compiler-path "${STARKNET_SIERRA_COMPILE_PATH}" --compiler-args '--allowed-libfuncs-list-file ./audited_cairo_libfuncs.json --add-pythonic-hints' --lite-mode +starknet-devnet --seed 42 exit 0 diff --git a/starknet/Scarb.lock b/starknet/Scarb.lock new file mode 100644 index 000000000..c77944cd8 --- /dev/null +++ b/starknet/Scarb.lock @@ -0,0 +1,14 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "openzeppelin" +version = "0.13.0" +source = "git+https://github.com/OpenZeppelin/cairo-contracts.git#592095f1cc344b50c269252a09626c678342301f" + +[[package]] +name = "sx" +version = "0.1.0" +dependencies = [ + "openzeppelin", +] diff --git a/starknet/Scarb.toml b/starknet/Scarb.toml index d782b13c6..a9f10e116 100644 --- a/starknet/Scarb.toml +++ b/starknet/Scarb.toml @@ -12,7 +12,7 @@ casm-add-pythonic-hints = true build-external-contracts = ["openzeppelin::account::account::Account", "openzeppelin::account::interface::AccountABI"] [dependencies] -openzeppelin = { git = "https://github.com/snapshot-labs/openzeppelin-cairo-contracts.git", branch = "feat/erc20votes-#631-frozen" } +openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", version = "0.13.0" } starknet = ">=2.2.0" [scripts] diff --git a/starknet/src/authenticators/eth_sig.cairo b/starknet/src/authenticators/eth_sig.cairo index a01be109b..f62effc79 100644 --- a/starknet/src/authenticators/eth_sig.cairo +++ b/starknet/src/authenticators/eth_sig.cairo @@ -89,14 +89,14 @@ mod EthSigAuthenticator { use starknet::{ContractAddress, EthAddress}; use sx::interfaces::{ISpaceDispatcher, ISpaceDispatcherTrait}; use sx::types::{Strategy, IndexedStrategy, Choice, UserAddress}; - use sx::utils::{EIP712, LegacyHashEthAddress, LegacyHashUsedSalts, ByteReverse}; + use sx::utils::{EIP712, LegacyHashEthAddress, ByteReverse}; #[storage] struct Storage { _used_salts: LegacyMap::<(EthAddress, u256), bool> } - #[external(v0)] + #[abi(embed_v0)] impl EthSigAuthenticator of IEthSigAuthenticator { fn authenticate_propose( ref self: ContractState, diff --git a/starknet/src/authenticators/eth_tx.cairo b/starknet/src/authenticators/eth_tx.cairo index 5cefee58b..a0845c209 100644 --- a/starknet/src/authenticators/eth_tx.cairo +++ b/starknet/src/authenticators/eth_tx.cairo @@ -69,7 +69,6 @@ mod EthTxAuthenticator { use starknet::{ContractAddress, EthAddress, Felt252TryIntoEthAddress, EthAddressIntoFelt252,}; use sx::interfaces::{ISpaceDispatcher, ISpaceDispatcherTrait}; use sx::types::{UserAddress, Strategy, IndexedStrategy, Choice}; - use sx::utils::LegacyHashFelt252EthAddress; use sx::utils::constants::{PROPOSE_SELECTOR, VOTE_SELECTOR, UPDATE_PROPOSAL_SELECTOR}; #[storage] @@ -78,7 +77,7 @@ mod EthTxAuthenticator { _commits: LegacyMap::<(felt252, EthAddress), bool> } - #[external(v0)] + #[abi(embed_v0)] impl EthTxAuthenticator of IEthTxAuthenticator { fn authenticate_propose( ref self: ContractState, diff --git a/starknet/src/authenticators/stark_sig.cairo b/starknet/src/authenticators/stark_sig.cairo index 5c9498273..5912f3596 100644 --- a/starknet/src/authenticators/stark_sig.cairo +++ b/starknet/src/authenticators/stark_sig.cairo @@ -88,7 +88,7 @@ mod StarkSigAuthenticator { _used_salts: LegacyMap::<(ContractAddress, felt252), bool> } - #[external(v0)] + #[abi(embed_v0)] impl StarkSigAuthenticator of IStarkSigAuthenticator { fn authenticate_propose( ref self: ContractState, diff --git a/starknet/src/authenticators/stark_tx.cairo b/starknet/src/authenticators/stark_tx.cairo index bf695d57d..bd293de13 100644 --- a/starknet/src/authenticators/stark_tx.cairo +++ b/starknet/src/authenticators/stark_tx.cairo @@ -70,7 +70,7 @@ mod StarkTxAuthenticator { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl StarkTxAuthenticator of IStarkTxAuthenticator { fn authenticate_propose( ref self: ContractState, diff --git a/starknet/src/execution_strategies/eth_relayer.cairo b/starknet/src/execution_strategies/eth_relayer.cairo index c31c8a489..fe5328b31 100644 --- a/starknet/src/execution_strategies/eth_relayer.cairo +++ b/starknet/src/execution_strategies/eth_relayer.cairo @@ -3,6 +3,7 @@ mod EthRelayerExecutionStrategy { use starknet::{info, syscalls, EthAddress}; use sx::interfaces::IExecutionStrategy; use sx::types::{Proposal, ProposalStatus}; + use starknet::SyscallResultTrait; #[storage] struct Storage {} @@ -20,7 +21,7 @@ mod EthRelayerExecutionStrategy { /// * votes_against - The number of votes against the proposal. /// * votes_abstain - The number of votes abstaining from the proposal. /// * payload - An array containing the serialized L1 execution strategy address and the L1 execution hash. - #[external(v0)] + #[abi(embed_v0)] impl EthRelayerExecutionStrategy of IExecutionStrategy { fn execute( ref self: ContractState, @@ -43,9 +44,9 @@ mod EthRelayerExecutionStrategy { // Decode payload into L1 execution strategy and L1 (keccak) execution hash let mut payload = payload.span(); - let (l1_execution_strategy, l1_execution_hash) = Serde::<( - EthAddress, u256 - )>::deserialize(ref payload) + let (l1_execution_strategy, l1_execution_hash) = Serde::< + (EthAddress, u256) + >::deserialize(ref payload) .unwrap(); // Serialize the payload to be sent to the L1 execution strategy @@ -58,7 +59,8 @@ mod EthRelayerExecutionStrategy { votes_abstain.serialize(ref l1_payload); l1_execution_hash.serialize(ref l1_payload); - syscalls::send_message_to_l1_syscall(l1_execution_strategy.into(), l1_payload.span()); + syscalls::send_message_to_l1_syscall(l1_execution_strategy.into(), l1_payload.span()) + .unwrap_syscall(); } fn get_strategy_type(self: @ContractState) -> felt252 { diff --git a/starknet/src/execution_strategies/no_execution_simple_majority.cairo b/starknet/src/execution_strategies/no_execution_simple_majority.cairo index e3b014238..42f06f71b 100644 --- a/starknet/src/execution_strategies/no_execution_simple_majority.cairo +++ b/starknet/src/execution_strategies/no_execution_simple_majority.cairo @@ -10,7 +10,7 @@ mod NoExecutionSimpleMajorityExecutionStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl NoExecutionSimpleMajorityExecutionStrategy of IExecutionStrategy { fn execute( ref self: ContractState, diff --git a/starknet/src/execution_strategies/timelock.cairo b/starknet/src/execution_strategies/timelock.cairo index 799b07bc7..dff1304f6 100644 --- a/starknet/src/execution_strategies/timelock.cairo +++ b/starknet/src/execution_strategies/timelock.cairo @@ -33,17 +33,24 @@ trait ITimelockExecutionStrategy { mod TimelockExecutionStrategy { use core::zeroable::Zeroable; use starknet::{ContractAddress, info, syscalls}; - use openzeppelin::access::ownable::Ownable; + use openzeppelin::access::ownable::OwnableComponent; use sx::interfaces::IExecutionStrategy; use super::ITimelockExecutionStrategy; use sx::types::{Proposal, ProposalStatus}; use sx::utils::{SimpleQuorum, SpaceManager}; + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + + impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl OwnableImpl = OwnableComponent::OwnableImpl; + #[storage] struct Storage { _timelock_delay: u32, _veto_guardian: ContractAddress, - _proposal_execution_time: LegacyMap:: + _proposal_execution_time: LegacyMap::, + #[substorage(v0)] + ownable: OwnableComponent::Storage } #[event] @@ -56,7 +63,9 @@ mod TimelockExecutionStrategy { ProposalQueued: ProposalQueued, CallExecuted: CallExecuted, ProposalExecuted: ProposalExecuted, - ProposalVetoed: ProposalVetoed + ProposalVetoed: ProposalVetoed, + #[flat] + OwnableEvent: OwnableComponent::Event } #[derive(Drop, PartialEq, starknet::Event)] @@ -121,10 +130,7 @@ mod TimelockExecutionStrategy { timelock_delay: u32, quorum: u256 ) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::initializer(ref state, owner); + self.ownable.initializer(owner); let mut state = SimpleQuorum::unsafe_new_contract_state(); SimpleQuorum::InternalImpl::initializer(ref state, quorum); @@ -136,7 +142,7 @@ mod TimelockExecutionStrategy { self._veto_guardian.write(veto_guardian); } - #[external(v0)] + #[abi(embed_v0)] impl ExecutionStrategy of IExecutionStrategy { fn execute( ref self: ContractState, @@ -183,9 +189,7 @@ mod TimelockExecutionStrategy { ) ); }, - Option::None(()) => { - break; - } + Option::None(()) => { break; } }; } } @@ -208,7 +212,7 @@ mod TimelockExecutionStrategy { } } - #[external(v0)] + #[abi(embed_v0)] impl TimelockExecutionStrategy of ITimelockExecutionStrategy { fn execute_queued_proposal(ref self: ContractState, mut payload: Span) { let execution_payload_hash = poseidon::poseidon_hash_span(payload); @@ -232,9 +236,7 @@ mod TimelockExecutionStrategy { self.emit(Event::CallExecuted(CallExecuted { call: call })); }, - Option::None(()) => { - break; - } + Option::None(()) => { break; } }; }; @@ -262,10 +264,7 @@ mod TimelockExecutionStrategy { } fn set_veto_guardian(ref self: ContractState, new_veto_guardian: ContractAddress) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); self._veto_guardian.write(new_veto_guardian); self @@ -279,10 +278,7 @@ mod TimelockExecutionStrategy { } fn set_timelock_delay(ref self: ContractState, new_timelock_delay: u32) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); self._timelock_delay.write(new_timelock_delay); self @@ -298,19 +294,13 @@ mod TimelockExecutionStrategy { } fn enable_space(ref self: ContractState, space: ContractAddress) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); let mut state = SpaceManager::unsafe_new_contract_state(); SpaceManager::InternalImpl::enable_space(ref state, space); } fn disable_space(ref self: ContractState, space: ContractAddress) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); let mut state = SpaceManager::unsafe_new_contract_state(); SpaceManager::InternalImpl::disable_space(ref state, space); } @@ -322,25 +312,17 @@ mod TimelockExecutionStrategy { SpaceManager::InternalImpl::is_space_enabled(@state, space) } + // TODO: use Ownable impl as abi_embed(v0)? fn owner(self: @ContractState) -> ContractAddress { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::owner(@state) + self.ownable.owner() } fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::transfer_ownership(ref state, new_owner); + self.ownable.transfer_ownership(new_owner); } fn renounce_ownership(ref self: ContractState) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::renounce_ownership(ref state); + self.ownable.renounce_ownership(); } } diff --git a/starknet/src/factory/factory.cairo b/starknet/src/factory/factory.cairo index 58b6e077b..f70a01c99 100644 --- a/starknet/src/factory/factory.cairo +++ b/starknet/src/factory/factory.cairo @@ -18,12 +18,12 @@ mod Factory { use sx::utils::constants::INITIALIZE_SELECTOR; #[event] - #[derive(Drop, starknet::Event)] + #[derive(Drop, PartialEq, starknet::Event)] enum Event { NewContractDeployed: NewContractDeployed } - #[derive(Drop, starknet::Event)] + #[derive(Drop, PartialEq, starknet::Event)] struct NewContractDeployed { class_hash: ClassHash, contract_address: ContractAddress @@ -32,7 +32,7 @@ mod Factory { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl Factory of IFactory { fn deploy( ref self: ContractState, diff --git a/starknet/src/lib.cairo b/starknet/src/lib.cairo index e5686a55c..9e28cc682 100644 --- a/starknet/src/lib.cairo +++ b/starknet/src/lib.cairo @@ -130,8 +130,8 @@ mod utils { mod legacy_hash; use legacy_hash::{ - LegacyHashEthAddress, LegacyHashFelt252EthAddress, LegacyHashUsedSalts, LegacyHashChoice, - LegacyHashUserAddress, LegacyHashVotePower, LegacyHashVoteRegistry, LegacyHashSpanFelt252 + LegacyHashEthAddress, LegacyHashChoice, LegacyHashUserAddress, LegacyHashVotePower, + LegacyHashVoteRegistry, LegacyHashSpanFelt252 }; mod math; diff --git a/starknet/src/proposal_validation_strategies/proposition_power.cairo b/starknet/src/proposal_validation_strategies/proposition_power.cairo index 7b564b9a1..7f56c563c 100644 --- a/starknet/src/proposal_validation_strategies/proposition_power.cairo +++ b/starknet/src/proposal_validation_strategies/proposition_power.cairo @@ -10,7 +10,7 @@ mod PropositionPowerProposalValidationStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl PropositionPowerProposalValidationStrategy of IProposalValidationStrategy { /// Designed to be used by spaces that which to use voting strategies to define who can create proposals. /// The allowed strategies simply need to be supplied in the `params` field. @@ -29,7 +29,9 @@ mod PropositionPowerProposalValidationStrategy { fn validate( self: @ContractState, author: UserAddress, - params: Span, // [proposal_threshold: u256, allowed_strategies: Array] + params: Span< + felt252 + >, // [proposal_threshold: u256, allowed_strategies: Array] user_params: Span // [user_strategies: Array] ) -> bool { proposition_power::validate(author, params, user_params) diff --git a/starknet/src/space/space.cairo b/starknet/src/space/space.cairo index 515f4bf91..bd8565e5e 100644 --- a/starknet/src/space/space.cairo +++ b/starknet/src/space/space.cairo @@ -2,7 +2,7 @@ mod Space { use starknet::{ClassHash, ContractAddress, info, Store, syscalls, SyscallResult,}; use starknet::storage_access::{StorePacking, StoreUsingPacking}; - use openzeppelin::access::ownable::Ownable; + use openzeppelin::access::ownable::OwnableComponent; use sx::interfaces::ISpace; use sx::interfaces::{ IProposalValidationStrategyDispatcher, IProposalValidationStrategyDispatcherTrait, @@ -20,6 +20,11 @@ mod Space { LegacyHashVoteRegistry, constants::{INITIALIZE_SELECTOR, POST_UPGRADE_INITIALIZER_SELECTOR} }; + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + + impl OwnableInternalImpl = OwnableComponent::InternalImpl; + impl OwnableImpl = OwnableComponent::OwnableImpl; + #[storage] struct Storage { _min_voting_duration: u32, @@ -35,10 +40,12 @@ mod Space { _proposals: LegacyMap::, _vote_power: LegacyMap::<(u256, Choice), u256>, _vote_registry: LegacyMap::<(u256, UserAddress), bool>, + #[substorage(v0)] + ownable: OwnableComponent::Storage, } #[event] - #[derive(Drop, starknet::Event)] + #[derive(Drop, PartialEq, starknet::Event)] enum Event { SpaceCreated: SpaceCreated, ProposalCreated: ProposalCreated, @@ -57,6 +64,8 @@ mod Space { ProposalValidationStrategyUpdated: ProposalValidationStrategyUpdated, VotingDelayUpdated: VotingDelayUpdated, Upgraded: Upgraded, + #[flat] + OwnableEvent: OwnableComponent::Event } #[derive(Drop, PartialEq, starknet::Event)] @@ -168,7 +177,7 @@ mod Space { dao_uri: Span, } - #[external(v0)] + #[abi(embed_v0)] impl Space of ISpace { fn initialize( ref self: ContractState, @@ -216,10 +225,7 @@ mod Space { assert(authenticators.len() != 0, 'empty authenticators'); assert(voting_strategies.len() == voting_strategy_metadata_uris.len(), 'len mismatch'); - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::initializer(ref state, owner); + self.ownable.initializer(owner); self.set_dao_uri(dao_uri); self .set_max_voting_duration( @@ -388,10 +394,7 @@ mod Space { } fn cancel(ref self: ContractState, proposal_id: u256) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); let mut proposal = self._proposals.read(proposal_id); InternalImpl::assert_proposal_exists(@proposal); @@ -446,8 +449,7 @@ mod Space { fn upgrade( ref self: ContractState, class_hash: ClassHash, initialize_calldata: Array ) -> SyscallResult<()> { - let state: Ownable::ContractState = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); assert(class_hash.is_non_zero(), 'Class Hash cannot be zero'); starknet::replace_class_syscall(class_hash)?; @@ -485,10 +487,7 @@ mod Space { } fn owner(self: @ContractState) -> ContractAddress { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::owner(@state) + self.ownable.owner() } fn max_voting_duration(self: @ContractState) -> u32 { @@ -548,10 +547,7 @@ mod Space { } fn update_settings(ref self: ContractState, input: UpdateSettingsCalldata) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let state = Ownable::unsafe_new_contract_state(); - Ownable::InternalImpl::assert_only_owner(@state); + self.ownable.assert_only_owner(); // Needed because the compiler will go crazy if we try to use `input` directly let _min_voting_duration = input.min_voting_duration; @@ -716,17 +712,11 @@ mod Space { } fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::transfer_ownership(ref state, new_owner); + self.ownable.transfer_ownership(new_owner); } fn renounce_ownership(ref self: ContractState) { - // Migration to components planned ; disregard the `unsafe` keyword, - // it is actually safe. - let mut state = Ownable::unsafe_new_contract_state(); - Ownable::OwnableImpl::renounce_ownership(ref state); + self.ownable.renounce_ownership(); } } @@ -763,9 +753,7 @@ mod Space { strategy_index.params.span() ); }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; total_voting_power @@ -812,9 +800,7 @@ mod Space { .write(cachedNextVotingStrategyIndex, strategy.clone()); cachedNextVotingStrategyIndex += 1_u8; }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; self._active_voting_strategies.write(cachedActiveVotingStrategies); @@ -825,12 +811,8 @@ mod Space { let mut cachedActiveVotingStrategies = self._active_voting_strategies.read(); loop { match _voting_strategies.pop_front() { - Option::Some(index) => { - cachedActiveVotingStrategies.set_bit(*index, false); - }, - Option::None => { - break; - }, + Option::Some(index) => { cachedActiveVotingStrategies.set_bit(*index, false); }, + Option::None => { break; }, }; }; @@ -845,9 +827,7 @@ mod Space { Option::Some(authenticator) => { self._authenticators.write(*authenticator, true); }, - Option::None => { - break; - }, + Option::None => { break; }, }; } } @@ -860,9 +840,7 @@ mod Space { Option::Some(authenticator) => { self._authenticators.write(*authenticator, false); }, - Option::None => { - break; - }, + Option::None => { break; }, }; } } diff --git a/starknet/src/tests/authenticators/stark_tx.cairo b/starknet/src/tests/authenticators/stark_tx.cairo index b94da1de6..f79549737 100644 --- a/starknet/src/tests/authenticators/stark_tx.cairo +++ b/starknet/src/tests/authenticators/stark_tx.cairo @@ -42,7 +42,7 @@ mod tests { #[available_gas(10000000000)] fn propose_update_vote() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = setup_stark_tx_auth(space, config.owner); let quorum = 1_u256; @@ -110,7 +110,7 @@ mod tests { #[should_panic(expected: ('Invalid Caller', 'ENTRYPOINT_FAILED'))] fn propose_invalid_caller() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = setup_stark_tx_auth(space, config.owner); let quorum = 1_u256; @@ -142,7 +142,7 @@ mod tests { #[should_panic(expected: ('Invalid Caller', 'ENTRYPOINT_FAILED'))] fn update_proposal_invalid_caller() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = setup_stark_tx_auth(space, config.owner); let quorum = 1_u256; @@ -192,7 +192,7 @@ mod tests { #[should_panic(expected: ('Invalid Caller', 'ENTRYPOINT_FAILED'))] fn vote_invalid_caller() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = setup_stark_tx_auth(space, config.owner); let quorum = 1_u256; diff --git a/starknet/src/tests/execution_strategies/timelock.cairo b/starknet/src/tests/execution_strategies/timelock.cairo index 056fb9c16..a2ef2b0e0 100644 --- a/starknet/src/tests/execution_strategies/timelock.cairo +++ b/starknet/src/tests/execution_strategies/timelock.cairo @@ -26,7 +26,7 @@ mod tests { fn setup_test() -> (Config, ISpaceDispatcher, ITimelockExecutionStrategyDispatcher) { let mut config = setup::setup(); config.min_voting_duration = 0; - let (factory, space) = setup::deploy(@config); + let (_, space) = setup::deploy(@config); let spaces = array![space.contract_address]; let timelock_delay = 100; @@ -225,7 +225,7 @@ mod tests { fn queue_duplicate_proposal() { let (config, space, timelock) = setup_test(); // Creating and voting on 2 proposals with the same payload - let (proposal_id_1, payload) = propose_and_vote( + let (proposal_id_1, _) = propose_and_vote( @config, space, timelock, @@ -299,7 +299,7 @@ mod tests { #[should_panic(expected: ('Invalid payload hash', 'ENTRYPOINT_FAILED'))] fn queue_invalid_payload() { let (config, space, timelock) = setup_test(); - let (proposal_id, payload) = propose_and_vote( + let (proposal_id, _) = propose_and_vote( @config, space, timelock, @@ -367,7 +367,7 @@ mod tests { #[should_panic(expected: ('Proposal Not Queued', 'ENTRYPOINT_FAILED'))] fn execute_not_queued() { let (config, space, timelock) = setup_test(); - let (proposal_id, payload) = propose_and_vote( + let (_, payload) = propose_and_vote( @config, space, timelock, @@ -392,12 +392,6 @@ mod tests { #[available_gas(10000000000)] fn multiple_proposal_txs() { let (config, space, timelock) = setup_test(); - let call = CallWithSalt { - to: space.contract_address, - selector: RENOUNCE_OWNERSHIP_SELECTOR, - calldata: array![], - salt: 0 - }; let mut new_settings: UpdateSettingsCalldata = Default::default(); new_settings.max_voting_duration = 1000; let mut new_settings_calldata = array![]; @@ -438,12 +432,6 @@ mod tests { #[should_panic(expected: ('Call Failed', 'ENTRYPOINT_FAILED'))] fn multiple_proposal_txs_one_fails() { let (config, space, timelock) = setup_test(); - let call = CallWithSalt { - to: space.contract_address, - selector: RENOUNCE_OWNERSHIP_SELECTOR, - calldata: array![], - salt: 0 - }; let mut new_settings: UpdateSettingsCalldata = Default::default(); new_settings.max_voting_duration = 1000; let mut new_settings_calldata = array![]; @@ -536,7 +524,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn set_timelock_delay() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); testing::set_caller_address(timelock.owner()); testing::set_contract_address(timelock.owner()); @@ -548,7 +536,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn set_timelock_delay_unauthorized() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); // Only the owner can set the timelock delay testing::set_caller_address(timelock.veto_guardian()); testing::set_contract_address(timelock.veto_guardian()); @@ -559,7 +547,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn set_veto_guardian() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); testing::set_caller_address(timelock.owner()); testing::set_contract_address(timelock.owner()); @@ -571,7 +559,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn set_veto_guardian_unauthorized() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); // Only the owner can set the veto guardian testing::set_caller_address(timelock.veto_guardian()); testing::set_contract_address(timelock.veto_guardian()); @@ -581,7 +569,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn set_owner() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); testing::set_caller_address(timelock.owner()); testing::set_contract_address(timelock.owner()); @@ -593,7 +581,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn set_owner_unauthorized() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); // Only the owner can transfer ownership testing::set_caller_address(timelock.veto_guardian()); testing::set_contract_address(timelock.veto_guardian()); @@ -603,7 +591,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn enable_space() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); testing::set_caller_address(timelock.owner()); testing::set_contract_address(timelock.owner()); @@ -618,7 +606,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn enable_space_unauthorized() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); // Only the owner can enable a space testing::set_caller_address(timelock.veto_guardian()); testing::set_contract_address(timelock.veto_guardian()); @@ -628,7 +616,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn disable_space() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); testing::set_caller_address(timelock.owner()); testing::set_contract_address(timelock.owner()); @@ -644,7 +632,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn disable_space_unauthorized() { - let (config, space, timelock) = setup_test(); + let (_, _, timelock) = setup_test(); // Only the owner can disable a space testing::set_caller_address(timelock.veto_guardian()); testing::set_contract_address(timelock.veto_guardian()); diff --git a/starknet/src/tests/factory/factory.cairo b/starknet/src/tests/factory/factory.cairo index 4ce77c510..cfa26444e 100644 --- a/starknet/src/tests/factory/factory.cairo +++ b/starknet/src/tests/factory/factory.cairo @@ -10,42 +10,43 @@ mod tests { use sx::space::space::Space::SpaceCreated; use sx::factory::factory::Factory::NewContractDeployed; - fn assert_space_event_is_correct( - event: SpaceCreated, config: Config, space_address: ContractAddress - ) { - assert(event.space == space_address, 'space'); - assert(event.owner == config.owner, 'owner'); - assert(event.min_voting_duration == config.min_voting_duration, 'min_voting_duration'); - assert(event.max_voting_duration == config.max_voting_duration, 'max_voting_duration'); - assert(event.voting_delay == config.voting_delay, 'voting_delay'); - assert( - event.proposal_validation_strategy == config.proposal_validation_strategy, - 'proposal_validation_strategy' - ); - assert( - event - .proposal_validation_strategy_metadata_uri == config - .proposal_validation_strategy_metadata_uri - .span(), - 'prop_val_strat_metadata' - ); - assert(event.voting_strategies == config.voting_strategies.span(), 'voting_strategies'); - assert( - event.voting_strategy_metadata_uris == config.voting_strategies_metadata_uris.span(), - 'voting_strat_metadata' + fn assert_space_event_is_correct(config: Config, space_address: ContractAddress) { + let event = utils::pop_log::(space_address).unwrap(); + let expected = Space::Event::SpaceCreated( + SpaceCreated { + space: space_address, + owner: config.owner, + min_voting_duration: config.min_voting_duration, + max_voting_duration: config.max_voting_duration, + voting_delay: config.voting_delay, + proposal_validation_strategy: config.proposal_validation_strategy, + proposal_validation_strategy_metadata_uri: config + .proposal_validation_strategy_metadata_uri + .span(), + voting_strategies: config.voting_strategies.span(), + voting_strategy_metadata_uris: config.voting_strategies_metadata_uris.span(), + authenticators: config.authenticators.span(), + metadata_uri: config.metadata_uri.span(), + dao_uri: config.dao_uri.span(), + } ); - assert(event.authenticators == config.authenticators.span(), 'authenticators'); - assert(event.metadata_uri == config.metadata_uri.span(), 'metadata_uri'); - assert(event.dao_uri == config.dao_uri.span(), 'dao_uri'); + + assert(event == expected, 'SpaceCreated event incorrect'); } fn assert_factory_event_is_correct( - factory_event: NewContractDeployed, space_address: ContractAddress + factory_address: ContractAddress, space_address: ContractAddress ) { - assert(factory_event.contract_address == space_address, 'space_contract_address'); - assert( - factory_event.class_hash == Space::TEST_CLASS_HASH.try_into().unwrap(), 'class_hash' + let factory_event = utils::pop_log::(factory_address).unwrap(); + + let expected = Factory::Event::NewContractDeployed( + NewContractDeployed { + contract_address: space_address, + class_hash: Space::TEST_CLASS_HASH.try_into().unwrap(), + } ); + + assert(factory_event == expected, 'Factory event incorrect'); } #[test] @@ -56,18 +57,13 @@ mod tests { let (factory, space) = deploy(@config); - let space_event = utils::pop_log::(space.contract_address).unwrap(); - // Ensure the space emitted the proper event - assert_space_event_is_correct(space_event, config, space.contract_address); + assert_space_event_is_correct(config, space.contract_address); - let factory_event = utils::pop_log::(factory.contract_address) - .unwrap(); - - assert_factory_event_is_correct(factory_event, space.contract_address); + // Ensure the facotry emitted the proper event + assert_factory_event_is_correct(factory.contract_address, space.contract_address); } - #[test] #[available_gas(10000000000)] fn deploy_reuse_salt() { @@ -78,7 +74,7 @@ mod tests { Factory::TEST_CLASS_HASH.try_into().unwrap(), 0, constructor_calldata.span(), false ) { Result::Ok((address, _)) => address, - Result::Err(e) => { + Result::Err(_) => { panic_with_felt252('deploy failed'); starknet::contract_address_const::<0>() }, @@ -92,10 +88,8 @@ mod tests { let config = setup(); let constructor_calldata = config.get_initialize_calldata(); - let space_address = factory - .deploy(space_class_hash, constructor_calldata.span(), salt_nonce); - let space_address_2 = factory - .deploy(space_class_hash, constructor_calldata.span(), salt_nonce); + let _ = factory.deploy(space_class_hash, constructor_calldata.span(), salt_nonce); + let _ = factory.deploy(space_class_hash, constructor_calldata.span(), salt_nonce); // TODO: this test should fail but doesn't fail currently because of how the test environment works } } diff --git a/starknet/src/tests/mocks/erc20_votes_preset.cairo b/starknet/src/tests/mocks/erc20_votes_preset.cairo index 10ad05694..5565b5738 100644 --- a/starknet/src/tests/mocks/erc20_votes_preset.cairo +++ b/starknet/src/tests/mocks/erc20_votes_preset.cairo @@ -6,186 +6,107 @@ #[starknet::contract] mod ERC20VotesPreset { use openzeppelin::governance::utils::interfaces::IVotes; - use openzeppelin::token::erc20::ERC20; - use openzeppelin::token::erc20::extensions::ERC20Votes; - use openzeppelin::token::erc20::interface::{IERC20, IERC20Camel}; - use openzeppelin::utils::structs::checkpoints::Checkpoint; + use openzeppelin::token::erc20::{ERC20Component}; + use openzeppelin::token::erc20::extensions::{ERC20VotesComponent}; + use openzeppelin::utils::nonces::NoncesComponent; + use openzeppelin::utils::structs::checkpoint::Checkpoint; + use openzeppelin::utils::cryptography::snip12::{SNIP12Metadata}; use starknet::ContractAddress; use starknet::contract_address_const; - #[storage] - struct Storage {} - - // - // Hooks - // - - impl ERC20VotesHooksImpl of ERC20::ERC20HooksTrait { - fn _after_update( - ref self: ERC20::ContractState, - from: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) { - let mut unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::InternalImpl::transfer_voting_units( - ref unsafe_state, from, recipient, amount - ); - } - } - - #[constructor] - fn constructor( - ref self: ContractState, - name: felt252, - symbol: felt252, - initial_supply: u256, - recipient: ContractAddress - ) { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::InternalImpl::initializer(ref unsafe_state, name, symbol); - ERC20::InternalImpl::_mint::( - ref unsafe_state, recipient, initial_supply - ); - } - - // - // External - // - #[external(v0)] - impl ERC20Impl of IERC20 { - fn name(self: @ContractState) -> felt252 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::name(@unsafe_state) - } - - fn symbol(self: @ContractState) -> felt252 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::symbol(@unsafe_state) - } - - fn decimals(self: @ContractState) -> u8 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::decimals(@unsafe_state) - } - - fn total_supply(self: @ContractState) -> u256 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::total_supply(@unsafe_state) - } + component!(path: ERC20Component, storage: erc20, event: ERC20Event); + component!(path: ERC20VotesComponent, storage: erc20_votes, event: ERC20VotesEvent); + component!(path: NoncesComponent, storage: nonces, event: NoncesEvent); - fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::balance_of(@unsafe_state, account) - } + #[abi(embed_v0)] + impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl; + impl ERC20InternalImpl = ERC20Component::InternalImpl; - fn allowance( - self: @ContractState, owner: ContractAddress, spender: ContractAddress - ) -> u256 { - let unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::allowance(@unsafe_state, owner, spender) - } + #[abi(embed_v0)] + impl ERC20VotesImpl = ERC20VotesComponent::ERC20VotesImpl; + impl ERC20VotesInternalImpl = ERC20VotesComponent::InternalImpl; - fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - let sender = starknet::get_caller_address(); - ERC20::InternalImpl::_transfer::( - ref unsafe_state, sender, recipient, amount - ); - true - } + impl NoncesImpl = NoncesComponent::NoncesImpl; - fn transfer_from( - ref self: ContractState, - sender: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) -> bool { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - let caller = starknet::get_caller_address(); - ERC20::InternalImpl::_spend_allowance(ref unsafe_state, sender, caller, amount); - ERC20::InternalImpl::_transfer::( - ref unsafe_state, sender, recipient, amount - ); - true + impl SNIP12MetadataImpl of SNIP12Metadata { + fn name() -> felt252 { + 'toto' // TODO } - fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::ERC20Impl::approve(ref unsafe_state, spender, amount) + fn version() -> felt252 { + '1.0.0' // TODO } } - #[external(v0)] - fn increase_allowance( - ref self: ContractState, spender: ContractAddress, added_value: u256 - ) -> bool { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::InternalImpl::_increase_allowance(ref unsafe_state, spender, added_value) + #[storage] + struct Storage { + #[substorage(v0)] + erc20: ERC20Component::Storage, + #[substorage(v0)] + erc20_votes: ERC20VotesComponent::Storage, + #[substorage(v0)] + nonces: NoncesComponent::Storage, } - #[external(v0)] - fn decrease_allowance( - ref self: ContractState, spender: ContractAddress, subtracted_value: u256 - ) -> bool { - let mut unsafe_state = ERC20::unsafe_new_contract_state(); - ERC20::InternalImpl::_decrease_allowance(ref unsafe_state, spender, subtracted_value) + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + ERC20Event: ERC20Component::Event, + #[flat] + ERC20VotesEvent: ERC20VotesComponent::Event, + #[flat] + NoncesEvent: NoncesComponent::Event, } - #[external(v0)] - impl VotesImpl of IVotes { - fn get_votes(self: @ContractState, account: ContractAddress) -> u256 { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::get_votes(@unsafe_state, account) - } - - fn get_past_votes(self: @ContractState, account: ContractAddress, timepoint: u64) -> u256 { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::get_past_votes(@unsafe_state, account, timepoint) - } - - fn get_past_total_supply(self: @ContractState, timepoint: u64) -> u256 { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::get_past_total_supply(@unsafe_state, timepoint) - } - - fn delegates(self: @ContractState, account: ContractAddress) -> ContractAddress { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::delegates(@unsafe_state, account) - } + // + // Hooks + // - fn delegate(ref self: ContractState, delegatee: ContractAddress) { - let mut unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::delegate(ref unsafe_state, delegatee); + impl ERC20VotesHooksImpl of ERC20Component::ERC20HooksTrait { + fn before_update( + ref self: ERC20Component::ComponentState, + from: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) { // Nothing to do } - fn delegate_by_sig( - ref self: ContractState, - delegator: ContractAddress, - delegatee: ContractAddress, - nonce: felt252, - expiry: u64, - signature: Array + fn after_update( + ref self: ERC20Component::ComponentState, + from: ContractAddress, + recipient: ContractAddress, + amount: u256 ) { - let mut unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::VotesImpl::delegate_by_sig( - ref unsafe_state, delegator, delegatee, nonce, expiry, signature - ); + // Access local state from component state + let mut contract_state = ERC20Component::HasComponent::get_contract_mut(ref self); + // Function from integrated component + contract_state.erc20_votes.transfer_voting_units(from, recipient, amount); } } + #[constructor] + fn constructor( + ref self: ContractState, + name: ByteArray, + symbol: ByteArray, + initial_supply: u256, + recipient: ContractAddress + ) { + self.erc20.initializer(name, symbol); + self.erc20._mint(recipient, initial_supply); + } + /// Get number of checkpoints for `account`. - #[external(v0)] + #[abi(embed_v0)] fn num_checkpoints(self: @ContractState, account: ContractAddress) -> u32 { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::InternalImpl::num_checkpoints(@unsafe_state, account) + self.erc20_votes.num_checkpoints(account) } /// Get the `pos`-th checkpoint for `account`. - #[external(v0)] + #[abi(embed_v0)] fn checkpoints(self: @ContractState, account: ContractAddress, pos: u32) -> Checkpoint { - let unsafe_state = ERC20Votes::unsafe_new_contract_state(); - ERC20Votes::InternalImpl::checkpoints(@unsafe_state, account, pos) + self.erc20_votes.checkpoints(account, pos) } } diff --git a/starknet/src/tests/mocks/executor.cairo b/starknet/src/tests/mocks/executor.cairo index 552a545b4..30f44291b 100644 --- a/starknet/src/tests/mocks/executor.cairo +++ b/starknet/src/tests/mocks/executor.cairo @@ -15,7 +15,7 @@ mod ExecutorExecutionStrategy { data: Array, } - #[external(v0)] + #[abi(embed_v0)] impl ExecutorExecutionStrategy of IExecutionStrategy { // Dummy function that will just execute the `Transaction` in the payload, without needing any quorum. fn execute( @@ -62,7 +62,7 @@ mod ExecutorWithoutTxExecutionStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl ExecutorWithoutTxExecutionStrategy of IExecutionStrategy { // Dummy function that will do nothing fn execute( diff --git a/starknet/src/tests/mocks/no_voting_power.cairo b/starknet/src/tests/mocks/no_voting_power.cairo index b4cd799ff..6eed36f4e 100644 --- a/starknet/src/tests/mocks/no_voting_power.cairo +++ b/starknet/src/tests/mocks/no_voting_power.cairo @@ -7,7 +7,7 @@ mod NoVotingPowerVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl NoVotingPowerVotingStrategy of IVotingStrategy { fn get_voting_power( self: @ContractState, diff --git a/starknet/src/tests/mocks/proposal_validation_always_fail.cairo b/starknet/src/tests/mocks/proposal_validation_always_fail.cairo index d0ba185a2..3be994271 100644 --- a/starknet/src/tests/mocks/proposal_validation_always_fail.cairo +++ b/starknet/src/tests/mocks/proposal_validation_always_fail.cairo @@ -2,13 +2,13 @@ mod AlwaysFailProposalValidationStrategy { use starknet::ContractAddress; use sx::types::UserAddress; + use sx::interfaces::{IProposalValidationStrategy,}; #[storage] struct Storage {} - #[external(v0)] - #[generate_trait] - impl AlwaysFailProposalValidationStrategy of IAlwaysFailProposalValidationStrategy { + #[abi(embed_v0)] + impl AlwaysFailProposalValidationStrategy of IProposalValidationStrategy { fn validate( self: @ContractState, author: UserAddress, diff --git a/starknet/src/tests/mocks/space_v2.cairo b/starknet/src/tests/mocks/space_v2.cairo index cd76a0e17..cd2e0dc4c 100644 --- a/starknet/src/tests/mocks/space_v2.cairo +++ b/starknet/src/tests/mocks/space_v2.cairo @@ -14,7 +14,7 @@ mod SpaceV2 { _var: felt252 } - #[external(v0)] + #[abi(embed_v0)] impl SpaceV2 of ISpaceV2 { fn post_upgrade_initializer(ref self: ContractState, var: felt252) { // Migration to components planned ; disregard the `unsafe` keyword, diff --git a/starknet/src/tests/mocks/vanilla_authenticator.cairo b/starknet/src/tests/mocks/vanilla_authenticator.cairo index 0e7b43bf6..1fce43d3b 100644 --- a/starknet/src/tests/mocks/vanilla_authenticator.cairo +++ b/starknet/src/tests/mocks/vanilla_authenticator.cairo @@ -16,7 +16,7 @@ mod VanillaAuthenticator { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl VanillaAuthenticator of IVanillaAuthenticator { fn authenticate( ref self: ContractState, @@ -26,10 +26,8 @@ mod VanillaAuthenticator { ) { // TODO: use if let Err(e) once it's supported match syscalls::call_contract_syscall(target, selector, data.span()) { - Result::Ok(a) => {}, - Result::Err(a) => { - assert(false, *a[0]); - }, + Result::Ok(_) => {}, + Result::Err(a) => { assert(false, *a[0]); }, }; } } diff --git a/starknet/src/tests/mocks/vanilla_execution_strategy.cairo b/starknet/src/tests/mocks/vanilla_execution_strategy.cairo index e754104f8..4e4814367 100644 --- a/starknet/src/tests/mocks/vanilla_execution_strategy.cairo +++ b/starknet/src/tests/mocks/vanilla_execution_strategy.cairo @@ -10,7 +10,7 @@ mod VanillaExecutionStrategy { _num_executed: felt252 } - #[external(v0)] + #[abi(embed_v0)] impl QuorumImpl of IQuorum { fn quorum(self: @ContractState) -> u256 { let mut state: SimpleQuorum::ContractState = SimpleQuorum::unsafe_new_contract_state(); @@ -20,7 +20,7 @@ mod VanillaExecutionStrategy { /// The vanilla execution strategy is a dummy execution strategy that simply increments a `_num_executed` variable for every /// newly executed proposal. It uses the `SimpleQuorum` method to determine whether a proposal is accepted or not. - #[external(v0)] + #[abi(embed_v0)] impl VanillaExecutionStrategy of IExecutionStrategy { fn execute( ref self: ContractState, @@ -68,7 +68,6 @@ mod VanillaExecutionStrategy { SimpleQuorum::InternalImpl::initializer(ref state, quorum); } - #[external(v0)] #[generate_trait] impl NumExecutedImpl of NumExecutedTrait { fn num_executed(self: @ContractState) -> felt252 { diff --git a/starknet/src/tests/mocks/vanilla_proposal_validation.cairo b/starknet/src/tests/mocks/vanilla_proposal_validation.cairo index fa5e90d49..dc240913b 100644 --- a/starknet/src/tests/mocks/vanilla_proposal_validation.cairo +++ b/starknet/src/tests/mocks/vanilla_proposal_validation.cairo @@ -7,7 +7,7 @@ mod VanillaProposalValidationStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl VanillaProposalValidationStrategy of IProposalValidationStrategy { /// Vanilla validation strategy that always returns true. fn validate( diff --git a/starknet/src/tests/mocks/vanilla_voting_strategy.cairo b/starknet/src/tests/mocks/vanilla_voting_strategy.cairo index 18657c715..9f4a3f2cf 100644 --- a/starknet/src/tests/mocks/vanilla_voting_strategy.cairo +++ b/starknet/src/tests/mocks/vanilla_voting_strategy.cairo @@ -6,7 +6,7 @@ mod VanillaVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl VanillaVotingStrategy of IVotingStrategy { /// Vanilla voting strategy that returns 1 for all voters. fn get_voting_power( diff --git a/starknet/src/tests/proposal_validation_strategies/proposition_power.cairo b/starknet/src/tests/proposal_validation_strategies/proposition_power.cairo index 26f9481d6..da467fbb6 100644 --- a/starknet/src/tests/proposal_validation_strategies/proposition_power.cairo +++ b/starknet/src/tests/proposal_validation_strategies/proposition_power.cairo @@ -260,7 +260,12 @@ mod tests { // deploy erc20 voting strategy let owner = starknet::contract_address_const::<'owner'>(); - let mut constructor = array!['TEST', 'TST']; + let mut constructor = array![]; + let name: ByteArray = "TEST"; + let symbol: ByteArray = "TST"; + + name.serialize(ref constructor); + symbol.serialize(ref constructor); SUPPLY.serialize(ref constructor); owner.serialize(ref constructor); diff --git a/starknet/src/tests/setup/setup.cairo b/starknet/src/tests/setup/setup.cairo index 4db762fcb..e64950a86 100644 --- a/starknet/src/tests/setup/setup.cairo +++ b/starknet/src/tests/setup/setup.cairo @@ -52,7 +52,6 @@ mod setup { let max_voting_duration = 2; let min_voting_duration = 1; let voting_delay = 1; - let quorum = u256_from_felt252(1); // Deploy Vanilla Authenticator let (vanilla_authenticator_address, _) = deploy_syscall( @@ -83,20 +82,6 @@ mod setup { voting_strategies .append(Strategy { address: vanilla_voting_strategy_address, params: array![] }); - // Deploy Vanilla Execution Strategy - let mut initializer_calldata = array![]; - quorum.serialize(ref initializer_calldata); - let (vanilla_execution_strategy_address, _) = deploy_syscall( - VanillaExecutionStrategy::TEST_CLASS_HASH.try_into().unwrap(), - 0, - initializer_calldata.span(), - false - ) - .unwrap(); - let vanilla_execution_strategy = StrategyImpl::from_address( - vanilla_execution_strategy_address - ); - let proposal_validation_strategy_metadata_uri = array!['https:://rick.roll']; let voting_strategies_metadata_uris = array![array![]]; let dao_uri = array!['https://dao.uri']; @@ -126,7 +111,7 @@ mod setup { Factory::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false ) { Result::Ok((address, _)) => address, - Result::Err(e) => { + Result::Err(_) => { panic_with_felt252('deploy failed'); contract_address_const::<0>() } @@ -138,7 +123,7 @@ mod setup { let space_address = match factory.deploy(space_class_hash, initializer_calldata.span(), salt_nonce) { Result::Ok(address) => address, - Result::Err(e) => { + Result::Err(_) => { panic_with_felt252('deploy failed'); contract_address_const::<0>() }, diff --git a/starknet/src/tests/space/space.cairo b/starknet/src/tests/space/space.cairo index e1b426054..58259d7a6 100644 --- a/starknet/src/tests/space/space.cairo +++ b/starknet/src/tests/space/space.cairo @@ -20,7 +20,6 @@ mod tests { use sx::tests::utils::strategy_trait::{StrategyImpl, StrategyDefault}; use sx::tests::mocks::executor::ExecutorWithoutTxExecutionStrategy; - fn assert_correct_proposal_event( space_address: ContractAddress, proposal_id: u256, @@ -29,13 +28,11 @@ mod tests { payload: Span, metadata_uri: Span, ) { - let event = utils::pop_log::(space_address).unwrap(); - - assert(event.proposal_id == proposal_id, 'proposal_id incorrect'); - assert(event.author == author, 'voter incorrect'); - assert(event.proposal == proposal, 'proposal incorrect'); - assert(event.payload == payload, 'payload incorrect'); - assert(event.metadata_uri == metadata_uri, 'metadata_uri incorrect'); + let event = utils::pop_log::(space_address).unwrap(); + let expected = Space::Event::ProposalCreated( + ProposalCreated { proposal_id, author, proposal, payload, metadata_uri } + ); + assert(event == expected, 'Proposal event incorrect'); } fn assert_correct_update_proposal_event( @@ -44,11 +41,11 @@ mod tests { execution_strategy: Strategy, metadata_uri: Span, ) { - let event = utils::pop_log::(space_address).unwrap(); - - assert(event.proposal_id == proposal_id, 'proposal_id incorrect'); - assert(event.execution_strategy == execution_strategy, 'execution_strategy incorrect'); - assert(event.metadata_uri == metadata_uri, 'metadata_uri incorrect'); + let event = utils::pop_log::(space_address).unwrap(); + let expected = Space::Event::ProposalUpdated( + ProposalUpdated { proposal_id, execution_strategy, metadata_uri } + ); + assert(event == expected, 'Update event should be correct'); } fn assert_correct_vote_cast_event( @@ -59,13 +56,11 @@ mod tests { voting_power: u256, metadata_uri: Span, ) { - let event = utils::pop_log::(space_address).unwrap(); - - assert(event.proposal_id == proposal_id, 'Proposal ID should be correct'); - assert(event.voter == voter, 'Voter should be correct'); - assert(event.choice == choice, 'Choice should be correct'); - assert(event.voting_power == voting_power, 'Voting power should be correct'); - assert(event.metadata_uri == metadata_uri, 'Metadata URI should be correct'); + let event = utils::pop_log::(space_address).unwrap(); + let expected = Space::Event::VoteCast( + VoteCast { proposal_id, voter, choice, voting_power, metadata_uri } + ); + assert(event == expected, 'Vote event should be correct'); } #[test] @@ -338,8 +333,8 @@ mod tests { #[available_gas(10000000000)] fn propose_update_vote_execute() { let config = setup(); - let (factory, space) = deploy(@config); - let ISpaceDispatcher{contract_address: space_contract_address } = space; + let (_, space) = deploy(@config); + let ISpaceDispatcher { contract_address: space_contract_address } = space; utils::drop_events(space_contract_address, 3); @@ -387,8 +382,6 @@ mod tests { finalization_status: FinalizationStatus::Pending(()), active_voting_strategies: 1_u256, }; - let proposal = ISpaceDispatcher { contract_address: space_contract_address } - .proposals(1_u256); let payload = vanilla_execution_strategy.params.span(); @@ -456,7 +449,7 @@ mod tests { #[should_panic(expected: ('Proposal is not valid', 'ENTRYPOINT_FAILED'))] fn propose_failed_validation() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0) }; @@ -510,7 +503,7 @@ mod tests { #[should_panic(expected: ('Already finalized', 'ENTRYPOINT_FAILED'))] fn execute_already_finalized() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -574,7 +567,7 @@ mod tests { #[should_panic(expected: ('Invalid payload hash', 'ENTRYPOINT_FAILED'))] fn execute_invalid_payload() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -609,7 +602,7 @@ mod tests { #[available_gas(10000000000)] fn get_proposal_status() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -647,7 +640,7 @@ mod tests { #[should_panic(expected: ('Proposal does not exist', 'ENTRYPOINT_FAILED'))] fn get_proposal_status_invalid_proposal_id() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); space.get_proposal_status(0); } @@ -656,9 +649,8 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Already finalized', 'ENTRYPOINT_FAILED'))] fn cancel() { - let relayer = starknet::contract_address_const::<0x1234>(); let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0) @@ -723,7 +715,7 @@ mod tests { #[should_panic(expected: ('Proposal does not exist', 'ENTRYPOINT_FAILED'))] fn cancel_inexistent_proposal() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); testing::set_contract_address(config.owner); space.cancel(0); @@ -734,7 +726,7 @@ mod tests { #[should_panic(expected: ('Already finalized', 'ENTRYPOINT_FAILED'))] fn cancel_already_finalized() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -777,7 +769,7 @@ mod tests { #[should_panic(expected: ('Zero Address', 'ENTRYPOINT_FAILED'))] fn propose_zero_address() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -814,7 +806,7 @@ mod tests { #[should_panic(expected: ('Zero Address', 'ENTRYPOINT_FAILED'))] fn update_zero_address() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -853,7 +845,7 @@ mod tests { #[should_panic(expected: ('Already finalized', 'ENTRYPOINT_FAILED'))] fn update_already_finalized() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -901,7 +893,7 @@ mod tests { #[should_panic(expected: ('Invalid author', 'ENTRYPOINT_FAILED'))] fn update_invalid_author() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -941,7 +933,7 @@ mod tests { #[should_panic(expected: ('Voting period started', 'ENTRYPOINT_FAILED'))] fn update_voting_period_started() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -982,7 +974,7 @@ mod tests { #[should_panic(expected: ('Proposal does not exist', 'ENTRYPOINT_FAILED'))] fn update_inexistent_proposal() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), @@ -1024,7 +1016,7 @@ mod tests { #[should_panic(expected: ('Zero Address', 'ENTRYPOINT_FAILED'))] fn vote_zero_address() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let authenticator = IVanillaAuthenticatorDispatcher { contract_address: *config.authenticators.at(0), diff --git a/starknet/src/tests/space/update_settings.cairo b/starknet/src/tests/space/update_settings.cairo index b84de53b8..79a040a10 100644 --- a/starknet/src/tests/space/update_settings.cairo +++ b/starknet/src/tests/space/update_settings.cairo @@ -37,7 +37,7 @@ mod tests { #[available_gas(10000000000)] #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn update_unauthorized() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); testing::set_contract_address(starknet::contract_address_const::<'unauthorized'>()); @@ -57,10 +57,10 @@ mod tests { space.min_voting_duration() == input.min_voting_duration, 'Min voting duration not updated' ); - let expected_event = MinVotingDurationUpdated { - min_voting_duration: input.min_voting_duration - }; - assert_correct_event::(space.contract_address, expected_event); + let expected_event = Space::Event::MinVotingDurationUpdated( + MinVotingDurationUpdated { min_voting_duration: input.min_voting_duration } + ); + assert_correct_event::(space.contract_address, expected_event); } #[test] @@ -88,10 +88,10 @@ mod tests { space.max_voting_duration() == input.max_voting_duration, 'Max voting duration not updated' ); - let expected_event = MaxVotingDurationUpdated { - max_voting_duration: input.max_voting_duration - }; - assert_correct_event::(space.contract_address, expected_event); + let expected_event = Space::Event::MaxVotingDurationUpdated( + MaxVotingDurationUpdated { max_voting_duration: input.max_voting_duration } + ); + assert_correct_event::(space.contract_address, expected_event); } #[test] @@ -123,15 +123,15 @@ mod tests { 'Max voting duration not updated' ); - let expected_event = MinVotingDurationUpdated { - min_voting_duration: input.min_voting_duration - }; - assert_correct_event::(space.contract_address, expected_event); + let expected_event = Space::Event::MinVotingDurationUpdated( + MinVotingDurationUpdated { min_voting_duration: input.min_voting_duration } + ); + assert_correct_event::(space.contract_address, expected_event); - let expected_event = MaxVotingDurationUpdated { - max_voting_duration: input.max_voting_duration - }; - assert_correct_event::(space.contract_address, expected_event); + let expected_event = Space::Event::MaxVotingDurationUpdated( + MaxVotingDurationUpdated { max_voting_duration: input.max_voting_duration } + ); + assert_correct_event::(space.contract_address, expected_event); } #[test] @@ -158,41 +158,45 @@ mod tests { space.update_settings(input.clone()); assert(space.voting_delay() == input.voting_delay, 'Voting delay not updated'); - let expected = VotingDelayUpdated { voting_delay: input.voting_delay }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::VotingDelayUpdated( + VotingDelayUpdated { voting_delay: input.voting_delay } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] fn metadata_uri() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); let mut arr = array![]; 'hello!'.serialize(ref arr); input.metadata_uri = arr; space.update_settings(input.clone()); - let expected = MetadataUriUpdated { metadata_uri: input.metadata_uri.span() }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::MetadataUriUpdated( + MetadataUriUpdated { metadata_uri: input.metadata_uri.span() } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] fn dao_uri() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); input.dao_uri = array!['hello!']; space.update_settings(input.clone()); assert(space.dao_uri() == input.dao_uri, 'dao uri not updated'); - let expected = DaoUriUpdated { dao_uri: input.dao_uri.span() }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::DaoUriUpdated(DaoUriUpdated { dao_uri: input.dao_uri.span() }); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] fn proposal_validation_strategy() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); let randomStrategy = StrategyImpl::from_address( starknet::contract_address_const::<'randomStrategy'>() @@ -208,19 +212,21 @@ mod tests { space.proposal_validation_strategy() == input.proposal_validation_strategy, 'Proposal strategy not updated' ); - let expected = ProposalValidationStrategyUpdated { - proposal_validation_strategy: input.proposal_validation_strategy, - proposal_validation_strategy_metadata_uri: input - .proposal_validation_strategy_metadata_uri - .span() - }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::ProposalValidationStrategyUpdated( + ProposalValidationStrategyUpdated { + proposal_validation_strategy: input.proposal_validation_strategy, + proposal_validation_strategy_metadata_uri: input + .proposal_validation_strategy_metadata_uri + .span() + } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] fn add_authenticators() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); let auth1 = starknet::contract_address_const::<'authenticator1'>(); let auth2 = starknet::contract_address_const::<'authenticator2'>(); @@ -232,8 +238,10 @@ mod tests { assert(space.authenticators(auth1) == true, 'Authenticator 1 not added'); assert(space.authenticators(auth2) == true, 'Authenticator 2 not added'); - let expected = AuthenticatorsAdded { authenticators: input.authenticators_to_add.span() }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::AuthenticatorsAdded( + AuthenticatorsAdded { authenticators: input.authenticators_to_add.span() } + ); + assert_correct_event::(space.contract_address, expected); } #[test] @@ -248,16 +256,16 @@ mod tests { space.update_settings(input.clone()); assert(space.authenticators(auth1) == false, 'Authenticator not removed'); - let expected = AuthenticatorsRemoved { - authenticators: input.authenticators_to_remove.span() - }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::AuthenticatorsRemoved( + AuthenticatorsRemoved { authenticators: input.authenticators_to_remove.span() } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] fn add_voting_strategies() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); let vs1 = StrategyImpl::from_address( @@ -277,18 +285,20 @@ mod tests { assert(space.voting_strategies(2) == vs2, 'Voting strategy 2 not added'); assert(space.active_voting_strategies() == 0b111, 'Voting strategies not active'); - let expected = VotingStrategiesAdded { - voting_strategies: input.voting_strategies_to_add.span(), - voting_strategy_metadata_uris: input.voting_strategies_metadata_uris_to_add.span(), - }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::VotingStrategiesAdded( + VotingStrategiesAdded { + voting_strategies: input.voting_strategies_to_add.span(), + voting_strategy_metadata_uris: input.voting_strategies_metadata_uris_to_add.span(), + } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] #[should_panic(expected: ('len mismatch', 'ENTRYPOINT_FAILED'))] fn add_voting_strategies_mismatch() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); let vs1 = StrategyImpl::from_address( @@ -313,7 +323,7 @@ mod tests { #[test] #[available_gas(10000000000)] fn remove_voting_strategies() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); // First, add a new voting strategy @@ -338,17 +348,19 @@ mod tests { space.update_settings(input.clone()); assert(space.active_voting_strategies() == 0b10, 'strategy not removed'); - let expected = VotingStrategiesRemoved { - voting_strategy_indices: input.voting_strategies_to_remove.span() - }; - assert_correct_event::(space.contract_address, expected); + let expected = Space::Event::VotingStrategiesRemoved( + VotingStrategiesRemoved { + voting_strategy_indices: input.voting_strategies_to_remove.span() + } + ); + assert_correct_event::(space.contract_address, expected); } #[test] #[available_gas(10000000000)] #[should_panic(expected: ('No active voting strategy left', 'ENTRYPOINT_FAILED'))] fn remove_all_voting_strategies() { - let (config, space) = setup_update_settings(); + let (_, space) = setup_update_settings(); let mut input: UpdateSettingsCalldata = Default::default(); // Remove the first voting strategy diff --git a/starknet/src/tests/space/upgrade.cairo b/starknet/src/tests/space/upgrade.cairo index b282b19cb..39a6d1975 100644 --- a/starknet/src/tests/space/upgrade.cairo +++ b/starknet/src/tests/space/upgrade.cairo @@ -20,19 +20,20 @@ mod tests { }; use sx::tests::mocks::space_v2::{SpaceV2, ISpaceV2Dispatcher, ISpaceV2DispatcherTrait}; use starknet::ClassHash; + use starknet::SyscallResultTrait; #[test] #[available_gas(10000000000)] fn upgrade() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let new_implem = SpaceV2::TEST_CLASS_HASH.try_into().unwrap(); testing::set_contract_address(config.owner); // Now upgrade the implementation - space.upgrade(new_implem, array![7]); + space.upgrade(new_implem, array![7]).unwrap_syscall(); // Ensure it works let new_space = ISpaceV2Dispatcher { contract_address: space.contract_address }; @@ -44,7 +45,7 @@ mod tests { #[available_gas(10000000000)] fn upgrade_via_execution_strategy() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let proposal_id = space.next_proposal_id(); // New implementation is not a proposer space but a random contract (here, a proposal validation strategy). @@ -102,13 +103,13 @@ mod tests { #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] fn upgrade_unauthorized() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let new_implem = SpaceV2::TEST_CLASS_HASH.try_into().unwrap(); testing::set_contract_address(starknet::contract_address_const::<0xdead>()); // Upgrade should fail as caller is not owner - space.upgrade(new_implem, array![7]); + space.upgrade(new_implem, array![7]).unwrap_syscall(); } } diff --git a/starknet/src/tests/space/vote.cairo b/starknet/src/tests/space/vote.cairo index f7505fd86..579517c92 100644 --- a/starknet/src/tests/space/vote.cairo +++ b/starknet/src/tests/space/vote.cairo @@ -60,19 +60,18 @@ mod tests { voting_power: u256, metadata_uri: Span, ) { - let event = utils::pop_log::(space_address).unwrap(); - assert(event.proposal_id == proposal_id, 'Proposal ID should be correct'); - assert(event.voter == voter, 'Voter should be correct'); - assert(event.choice == choice, 'Choice should be correct'); - assert(event.voting_power == voting_power, 'Voting power should be correct'); - assert(event.metadata_uri == metadata_uri, 'Metadata URI should be correct'); + let event = utils::pop_log::(space_address).unwrap(); + let expected = Space::Event::VoteCast( + VoteCast { proposal_id, voter, choice, voting_power, metadata_uri } + ); + assert(event == expected, 'Vote event should be correct'); } #[test] #[available_gas(10000000000)] fn vote_for() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); @@ -114,7 +113,7 @@ mod tests { #[available_gas(10000000000)] fn vote_against() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -155,7 +154,7 @@ mod tests { #[available_gas(10000000000)] fn vote_abstain() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -196,7 +195,7 @@ mod tests { #[should_panic(expected: ('Voting period has not started', 'ENTRYPOINT_FAILED'))] fn vote_too_early() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -226,7 +225,7 @@ mod tests { #[should_panic(expected: ('Voting period has ended', 'ENTRYPOINT_FAILED'))] fn vote_too_late() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -259,7 +258,7 @@ mod tests { #[should_panic(expected: ('Already finalized', 'ENTRYPOINT_FAILED'))] fn vote_finalized_proposal() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -294,7 +293,7 @@ mod tests { #[should_panic(expected: ('Caller is not an authenticator', 'ENTRYPOINT_FAILED'))] fn vote_without_authenticator() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); let authenticator = IVanillaAuthenticatorDispatcher { @@ -322,7 +321,7 @@ mod tests { #[should_panic(expected: ('Voter has already voted', 'ENTRYPOINT_FAILED'))] fn vote_twice() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); @@ -355,7 +354,7 @@ mod tests { #[should_panic(expected: ('User has no voting power', 'ENTRYPOINT_FAILED'))] fn vote_no_voting_power() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); @@ -405,7 +404,7 @@ mod tests { #[should_panic(expected: ('Proposal does not exist', 'ENTRYPOINT_FAILED'))] fn vote_inexistant_proposal() { let config = setup(); - let (factory, space) = deploy(@config); + let (_, space) = deploy(@config); let execution_strategy = get_execution_strategy(); diff --git a/starknet/src/tests/voting_strategies/erc20_votes.cairo b/starknet/src/tests/voting_strategies/erc20_votes.cairo index 1281824cd..ed01f6843 100644 --- a/starknet/src/tests/voting_strategies/erc20_votes.cairo +++ b/starknet/src/tests/voting_strategies/erc20_votes.cairo @@ -2,8 +2,6 @@ mod tests { use sx::tests::mocks::erc20_votes_preset::ERC20VotesPreset; // temporary while we wait for scarb to fix their dependencies use sx::interfaces::{ISpaceDispatcher, ISpaceDispatcherTrait}; - use openzeppelin::token::erc20::presets::ERC20VotesPreset::ERC20Impl; - use openzeppelin::token::erc20::presets::ERC20VotesPreset::VotesImpl; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use openzeppelin::governance::utils::interfaces::votes::{ IVotes, IVotesDispatcher, IVotesDispatcherTrait @@ -25,8 +23,7 @@ mod tests { use sx::utils::constants::{PROPOSE_SELECTOR, VOTE_SELECTOR}; use sx::tests::mocks::vanilla_execution_strategy::VanillaExecutionStrategy; - const NAME: felt252 = 'TEST'; - const SYMBOL: felt252 = 'TST'; + const INITIAL_SUPPLY: u256 = 1_000; fn OWNER() -> ContractAddress { @@ -34,11 +31,22 @@ mod tests { } fn deploy_token_contract() -> ContractAddress { - // Deploy ERC20 - let constructor_data = array![ - NAME, SYMBOL, INITIAL_SUPPLY.low.into(), INITIAL_SUPPLY.high.into(), OWNER().into() - ]; + let NAME: ByteArray = "TEST"; + let SYMBOL: ByteArray = "TST"; + let mut constructor_data = array![]; + NAME.serialize(ref constructor_data); + SYMBOL.serialize(ref constructor_data); + INITIAL_SUPPLY.low.serialize(ref constructor_data); + INITIAL_SUPPLY.high.serialize(ref constructor_data); + OWNER().serialize(ref constructor_data); + + // let constructor_data = array![ + // NAME, SYMBOL, INITIAL_SUPPLY.low.into(), INITIAL_SUPPLY.high.into(), OWNER().into() + // ]; + // let constructor_data = (NAME, SYMBOL, INITIAL_SUPPLY.low, INITIAL_SUPPLY, OWNER()); + + // Deploy ERC20 let (token_contract, _) = syscalls::deploy_syscall( ERC20VotesPreset::TEST_CLASS_HASH.try_into().unwrap(), 0, @@ -66,7 +74,7 @@ mod tests { fn setup_space() -> (Config, ISpaceDispatcher) { let config = _setup(); - let (factory_address, space) = deploy(@config); + let (_, space) = deploy(@config); let token_contract = deploy_token_contract(); let erc20_voting_strategy = strategy_from_contract(token_contract); @@ -151,7 +159,7 @@ mod tests { #[test] #[available_gas(1000000000)] - fn works() { + fn scott_works() { let (config, space) = setup_space(); let vanilla_execution_strategy = get_vanilla_execution_strategy(); let accounts = setup_accounts(space.voting_strategies(1)); diff --git a/starknet/src/tests/voting_strategies/merkle_whitelist.cairo b/starknet/src/tests/voting_strategies/merkle_whitelist.cairo index 4df1574fd..081315035 100644 --- a/starknet/src/tests/voting_strategies/merkle_whitelist.cairo +++ b/starknet/src/tests/voting_strategies/merkle_whitelist.cairo @@ -11,9 +11,7 @@ mod merkle_utils { loop { match self.pop_front() { Option::Some(val) => output.append(val.clone()), - Option::None => { - break; - } + Option::None => { break; } }; }; output @@ -96,9 +94,7 @@ mod merkle_utils { Option::None => panic_with_felt252('Incorrect array length'), } }, - Option::None => { - break; - } + Option::None => { break; } }; }; next_level @@ -111,12 +107,8 @@ mod merkle_utils { let mut output = array![]; loop { match members_.pop_front() { - Option::Some(leaf) => { - output.append(leaf.hash()); - }, - Option::None => { - break; - }, + Option::Some(leaf) => { output.append(leaf.hash()); }, + Option::None => { break; }, }; }; output @@ -186,13 +178,11 @@ mod assert_valid_proof { let mut output = ArrayTrait::new(); output.append(value); - arr.pop_front(); // remove first element + arr.pop_front().unwrap(); // remove first element loop { match arr.pop_front() { Option::Some(v) => output.append(*v), - Option::None => { - break; - }, + Option::None => { break; }, }; }; output @@ -436,7 +426,6 @@ mod merkle_whitelist_voting_power { let timestamp = 0x1234; let index = 2; let leaf = *members.at(index); - let voter = leaf.address; let merkle_data = generate_merkle_data(members.span()); let root = generate_merkle_root(merkle_data.span()); diff --git a/starknet/src/types/indexed_strategy.cairo b/starknet/src/types/indexed_strategy.cairo index fc8b493bc..5160e7b18 100644 --- a/starknet/src/types/indexed_strategy.cairo +++ b/starknet/src/types/indexed_strategy.cairo @@ -31,9 +31,7 @@ impl IndexedStrategyImpl of IndexedStrategyTrait { // Update aforementioned bit. bit_map = bit_map | s; }, - Option::None => { - break; - }, + Option::None => { break; }, }; }; } diff --git a/starknet/src/types/strategy.cairo b/starknet/src/types/strategy.cairo index a99f4244b..0a6fcc3fd 100644 --- a/starknet/src/types/strategy.cairo +++ b/starknet/src/types/strategy.cairo @@ -1,5 +1,6 @@ use integer::BoundedU8; use starknet::{ContractAddress, StorageBaseAddress, Store, SyscallResult}; +use starknet::SyscallResultTrait; /// A strategy identified by an address #[derive(Clone, Drop, Option, Serde, starknet::Store)] @@ -67,7 +68,7 @@ impl StoreFelt252Array of Store> { ) -> SyscallResult<()> { // // Store the length of the array in the first storage slot. let len: u8 = value.len().try_into().expect('Storage - Span too large'); - Store::::write_at_offset(address_domain, base, offset, len); + Store::::write_at_offset(address_domain, base, offset, len).unwrap_syscall(); offset += Store::::size(); // Store the array elements sequentially @@ -76,15 +77,11 @@ impl StoreFelt252Array of Store> { Option::Some(element) => { match Store::::write_at_offset(address_domain, base, offset, element) { Result::Ok(()) => {}, - Result::Err(e) => { - break Result::Err(e); - } + Result::Err(e) => { break Result::Err(e); } } offset += Store::::size(); }, - Option::None(_) => { - break Result::Ok(()); - } + Option::None(_) => { break Result::Ok(()); } }; } } diff --git a/starknet/src/types/update_settings_calldata.cairo b/starknet/src/types/update_settings_calldata.cairo index 65e043967..400371526 100644 --- a/starknet/src/types/update_settings_calldata.cairo +++ b/starknet/src/types/update_settings_calldata.cairo @@ -54,25 +54,33 @@ impl NoUpdateFelt252 of NoUpdateTrait { impl NoUpdateContractAddress of NoUpdateTrait { fn no_update() -> ContractAddress { // First 248 bits - starknet::contract_address_const::<0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048>() + starknet::contract_address_const::< + 0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048 + >() } fn should_update(self: @ContractAddress) -> bool { - *self != starknet::contract_address_const::<0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048>() + *self != starknet::contract_address_const::< + 0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048 + >() } } impl NoUpdateStrategy of NoUpdateTrait { fn no_update() -> Strategy { Strategy { - address: starknet::contract_address_const::<0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048>(), + address: starknet::contract_address_const::< + 0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048 + >(), params: array![], } } fn should_update(self: @Strategy) -> bool { *self - .address != starknet::contract_address_const::<0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048>() + .address != starknet::contract_address_const::< + 0xf2cda9b13ed04e585461605c0d6e804933ca828111bd94d4e6a96c75e8b048 + >() } } @@ -83,9 +91,7 @@ impl NoUpdateString of NoUpdateTrait> { fn should_update(self: @Array) -> bool { match self.get(0) { - Option::Some(e) => { - *e.unbox() != 'No update' - }, + Option::Some(e) => { *e.unbox() != 'No update' }, Option::None => true, } } diff --git a/starknet/src/types/user_address.cairo b/starknet/src/types/user_address.cairo index b286a2a8c..51a8b8bb1 100644 --- a/starknet/src/types/user_address.cairo +++ b/starknet/src/types/user_address.cairo @@ -24,37 +24,25 @@ impl UserAddressImpl of UserAddressTrait { fn to_starknet_address(self: UserAddress) -> ContractAddress { match self { UserAddress::Starknet(address) => address, - UserAddress::Ethereum(_) => { - panic_with_felt252('Incorrect address type') - }, - UserAddress::Custom(_) => { - panic_with_felt252('Incorrect address type') - } + UserAddress::Ethereum(_) => { panic_with_felt252('Incorrect address type') }, + UserAddress::Custom(_) => { panic_with_felt252('Incorrect address type') } } } /// Returns the ethereum address. Panics if the address is not an ethereum address. fn to_ethereum_address(self: UserAddress) -> EthAddress { match self { - UserAddress::Starknet(_) => { - panic_with_felt252('Incorrect address type') - }, + UserAddress::Starknet(_) => { panic_with_felt252('Incorrect address type') }, UserAddress::Ethereum(address) => address, - UserAddress::Custom(_) => { - panic_with_felt252('Incorrect address type') - } + UserAddress::Custom(_) => { panic_with_felt252('Incorrect address type') } } } /// Returns the custom address. Panics if the address is not a custom address. fn to_custom_address(self: UserAddress) -> u256 { match self { - UserAddress::Starknet(_) => { - panic_with_felt252('Incorrect address type') - }, - UserAddress::Ethereum(_) => { - panic_with_felt252('Incorrect address type') - }, + UserAddress::Starknet(_) => { panic_with_felt252('Incorrect address type') }, + UserAddress::Ethereum(_) => { panic_with_felt252('Incorrect address type') }, UserAddress::Custom(address) => address, } } diff --git a/starknet/src/utils/eip712.cairo b/starknet/src/utils/eip712.cairo index 94da6eff0..4adeb7e42 100644 --- a/starknet/src/utils/eip712.cairo +++ b/starknet/src/utils/eip712.cairo @@ -1,6 +1,7 @@ #[starknet::contract] mod EIP712 { use starknet::{EthAddress, ContractAddress, secp256_trait}; + use starknet::eth_signature::verify_eth_signature; use starknet::secp256k1::Secp256k1Point; use sx::types::{Strategy, IndexedStrategy, Choice}; use sx::utils::{endian, ByteReverse, KeccakStructHash, TIntoU256}; @@ -38,9 +39,7 @@ mod EIP712 { user_proposal_validation_params, salt ); - secp256_trait::verify_eth_signature::( - digest, secp256_trait::signature_from_vrs(v, r, s), author - ); + verify_eth_signature(digest, secp256_trait::signature_from_vrs(v, r, s), author); } /// Verifies the signature of the vote calldata. @@ -60,9 +59,7 @@ mod EIP712 { .get_vote_digest( space, voter, proposal_id, choice, user_voting_strategies, metadata_uri ); - secp256_trait::verify_eth_signature::( - digest, secp256_trait::signature_from_vrs(v, r, s), voter - ); + verify_eth_signature(digest, secp256_trait::signature_from_vrs(v, r, s), voter); } /// Verifies the signature of the update proposal calldata. @@ -82,9 +79,7 @@ mod EIP712 { .get_update_proposal_digest( space, author, proposal_id, execution_strategy, metadata_uri, salt ); - secp256_trait::verify_eth_signature::( - digest, secp256_trait::signature_from_vrs(v, r, s), author - ); + verify_eth_signature(digest, secp256_trait::signature_from_vrs(v, r, s), author); } /// Returns the digest of the propose calldata. diff --git a/starknet/src/utils/endian.cairo b/starknet/src/utils/endian.cairo index cb70accc1..a187b2cf4 100644 --- a/starknet/src/utils/endian.cairo +++ b/starknet/src/utils/endian.cairo @@ -37,9 +37,7 @@ fn into_le_u64_array(self: Array) -> (Array, u64) { out.append(low_high); out.append(low_low); }, - Option::None => { - panic_with_felt252('Array should not be empty!'); - } + Option::None => { panic_with_felt252('Array should not be empty!'); } }; }; (out, overflow) diff --git a/starknet/src/utils/into.cairo b/starknet/src/utils/into.cairo index 39d01f17a..86475aee4 100644 --- a/starknet/src/utils/into.cairo +++ b/starknet/src/utils/into.cairo @@ -4,12 +4,8 @@ impl Felt252SpanIntoU256Array of Into, Array> { let mut arr = ArrayTrait::::new(); loop { match self.pop_front() { - Option::Some(num) => { - arr.append(integer::u256_from_felt252(*num)); - }, - Option::None(_) => { - break (); - }, + Option::Some(num) => { arr.append(integer::u256_from_felt252(*num)); }, + Option::None(_) => { break (); }, }; }; arr diff --git a/starknet/src/utils/keccak.cairo b/starknet/src/utils/keccak.cairo index 8681382ba..c84c92ec3 100644 --- a/starknet/src/utils/keccak.cairo +++ b/starknet/src/utils/keccak.cairo @@ -44,9 +44,7 @@ impl KeccakStructHashIndexedStrategyArray of KeccakStructHash::new(); loop { match self_.pop_front() { - Option::Some(item) => { - encoded_data.append(item.keccak_struct_hash()); - }, + Option::Some(item) => { encoded_data.append(item.keccak_struct_hash()); }, Option::None(_) => { break keccak::keccak_u256s_be_inputs(encoded_data.span()).byte_reverse(); } diff --git a/starknet/src/utils/legacy_hash.cairo b/starknet/src/utils/legacy_hash.cairo index 9e5dbd5f7..201200c59 100644 --- a/starknet/src/utils/legacy_hash.cairo +++ b/starknet/src/utils/legacy_hash.cairo @@ -15,14 +15,6 @@ impl LegacyHashEthAddress of LegacyHash { } } -impl LegacyHashFelt252EthAddress of LegacyHash<(felt252, EthAddress)> { - fn hash(state: felt252, value: (felt252, EthAddress)) -> felt252 { - let (_felt252, _eth_address) = value; - let state = LegacyHash::hash(state, _felt252); - LegacyHash::hash(state, _eth_address) - } -} - impl LegacyHashSpanFelt252 of LegacyHash> { fn hash(state: felt252, mut value: Span) -> felt252 { let len = value.len(); @@ -32,9 +24,7 @@ impl LegacyHashSpanFelt252 of LegacyHash> { Option::Some(item) => { call_data_state = LegacyHash::hash(call_data_state, *item); }, - Option::None(_) => { - break LegacyHash::hash(call_data_state, len); - }, + Option::None(_) => { break LegacyHash::hash(call_data_state, len); }, }; } } @@ -50,14 +40,6 @@ impl LegacyHashUserAddress of LegacyHash { } } -impl LegacyHashUsedSalts of LegacyHash<(EthAddress, u256)> { - fn hash(state: felt252, value: (EthAddress, u256)) -> felt252 { - let (addr, salt) = value; - let state = LegacyHash::hash(state, addr); - LegacyHash::hash(state, salt) - } -} - impl LegacyHashVotePower of LegacyHash<(u256, Choice)> { fn hash(state: felt252, value: (u256, Choice)) -> felt252 { let (proposal_id, choice) = value; diff --git a/starknet/src/utils/merkle.cairo b/starknet/src/utils/merkle.cairo index 10f7dcdca..20205f93b 100644 --- a/starknet/src/utils/merkle.cairo +++ b/starknet/src/utils/merkle.cairo @@ -43,9 +43,7 @@ fn compute_merkle_root(mut current: felt252, proof: Span) -> felt252 { current = LegacyHash::hash(*val, current); }; }, - Option::None => { - break current; - }, + Option::None => { break current; }, }; } } diff --git a/starknet/src/utils/proposition_power.cairo b/starknet/src/utils/proposition_power.cairo index 5c3c3da86..1a9a5b95c 100644 --- a/starknet/src/utils/proposition_power.cairo +++ b/starknet/src/utils/proposition_power.cairo @@ -30,14 +30,10 @@ fn get_cumulative_power( indexed_strategy.params.span(), ); }, - Option::None => { - panic_with_felt252('Invalid strategy index'); - }, + Option::None => { panic_with_felt252('Invalid strategy index'); }, }; }, - Option::None => { - break total_voting_power; - }, + Option::None => { break total_voting_power; }, }; } } @@ -48,9 +44,9 @@ fn validate( mut params: Span, // [proposal_threshold: u256, allowed_strategies: Array] mut user_params: Span // [user_strategies: Array] ) -> bool { - let (proposal_threshold, allowed_strategies) = Serde::<( - u256, Array - )>::deserialize(ref params) + let (proposal_threshold, allowed_strategies) = Serde::< + (u256, Array) + >::deserialize(ref params) .unwrap(); let user_strategies = Serde::>::deserialize(ref user_params).unwrap(); diff --git a/starknet/src/utils/simple_quorum.cairo b/starknet/src/utils/simple_quorum.cairo index 2f43c0ccf..0fe79eb62 100644 --- a/starknet/src/utils/simple_quorum.cairo +++ b/starknet/src/utils/simple_quorum.cairo @@ -61,7 +61,7 @@ mod SimpleQuorum { } } - #[external(v0)] + #[abi(embed_v0)] impl Quorum of IQuorum { fn quorum(self: @ContractState) -> u256 { self._quorum.read() diff --git a/starknet/src/utils/space_manager.cairo b/starknet/src/utils/space_manager.cairo index 5abfe86db..198799c67 100644 --- a/starknet/src/utils/space_manager.cairo +++ b/starknet/src/utils/space_manager.cairo @@ -35,9 +35,7 @@ mod SpaceManager { ); self._spaces.write(*space, true); }, - Option::None(()) => { - break; - } + Option::None(()) => { break; } }; } } diff --git a/starknet/src/utils/struct_hash.cairo b/starknet/src/utils/struct_hash.cairo index b6641847e..71953518d 100644 --- a/starknet/src/utils/struct_hash.cairo +++ b/starknet/src/utils/struct_hash.cairo @@ -43,12 +43,8 @@ impl StructHashIndexedStrategySpan of StructHash> { let mut encoded_data = array![]; loop { match self_.pop_front() { - Option::Some(item) => { - encoded_data.append(item.struct_hash()); - }, - Option::None(_) => { - break encoded_data.span().struct_hash(); - }, + Option::Some(item) => { encoded_data.append(item.struct_hash()); }, + Option::None(_) => { break encoded_data.span().struct_hash(); }, }; } } diff --git a/starknet/src/voting_strategies/erc20_votes.cairo b/starknet/src/voting_strategies/erc20_votes.cairo index 4e6808ff0..5c92611ec 100644 --- a/starknet/src/voting_strategies/erc20_votes.cairo +++ b/starknet/src/voting_strategies/erc20_votes.cairo @@ -10,7 +10,7 @@ mod ERC20VotesVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl ERC20VotesVotingStrategy of IVotingStrategy { /// Returns the total amount of delegated votes of `voter` at the given `timestamp`. /// A user must self-delegate if he wishes to have voting power. diff --git a/starknet/src/voting_strategies/evm_slot_value.cairo b/starknet/src/voting_strategies/evm_slot_value.cairo index ad15fb4c7..5da8f4a67 100644 --- a/starknet/src/voting_strategies/evm_slot_value.cairo +++ b/starknet/src/voting_strategies/evm_slot_value.cairo @@ -10,7 +10,7 @@ mod EvmSlotValueVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl EvmSlotValueVotingStrategy of IVotingStrategy { /// Returns the value of a slot in a mapping in an EVM contract at the block number corresponding to the given timestamp. /// @@ -40,9 +40,9 @@ mod EvmSlotValueVotingStrategy { let voter = voter.to_ethereum_address(); // Decode params and user_params - let (evm_contract_address, slot_index) = Serde::<( - EthAddress, u256 - )>::deserialize(ref params) + let (evm_contract_address, slot_index) = Serde::< + (EthAddress, u256) + >::deserialize(ref params) .unwrap(); let mpt_proof = Serde::>>::deserialize(ref user_params).unwrap(); @@ -62,7 +62,6 @@ mod EvmSlotValueVotingStrategy { } } - #[external(v0)] #[generate_trait] impl SingleSlotProofImpl of SingleSlotProofTrait { /// Queries the Timestamp Remapper contract for the closest L1 block number that occured before diff --git a/starknet/src/voting_strategies/merkle_whitelist.cairo b/starknet/src/voting_strategies/merkle_whitelist.cairo index 310d31463..dad7444e7 100644 --- a/starknet/src/voting_strategies/merkle_whitelist.cairo +++ b/starknet/src/voting_strategies/merkle_whitelist.cairo @@ -7,7 +7,7 @@ mod MerkleWhitelistVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl MerkleWhitelistImpl of IVotingStrategy { /// Returns the voting power of a members of a merkle tree. /// The merkle tree root is stored in the strategy parameters (defined by the space owner). diff --git a/starknet/src/voting_strategies/oz_votes_storage_proof.cairo b/starknet/src/voting_strategies/oz_votes_storage_proof.cairo index 7c299b85f..7076a09a1 100644 --- a/starknet/src/voting_strategies/oz_votes_storage_proof.cairo +++ b/starknet/src/voting_strategies/oz_votes_storage_proof.cairo @@ -10,7 +10,7 @@ mod OZVotesStorageProofVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl OZVotesStorageProofVotingStrategy of IVotingStrategy { /// Returns the delegated voting power of `voter` at the block number corresponding to `timestamp` for tokens that implement OZVotes. /// @@ -31,20 +31,22 @@ mod OZVotesStorageProofVotingStrategy { timestamp: u32, voter: UserAddress, mut params: Span, // [contract_address: address, slot_index: u256] - mut user_params: Span, // [checkpoint_index: u32, checkpoint_mpt_proof: u64[][], exclusion_mpt_proof: u64[][]] + mut user_params: Span< + felt252 + >, // [checkpoint_index: u32, checkpoint_mpt_proof: u64[][], exclusion_mpt_proof: u64[][]] ) -> u256 { // Cast voter address to an Ethereum address // Will revert if the address is not a valid Ethereum address let voter = voter.to_ethereum_address(); // Decode params and user_params - let (evm_contract_address, slot_index) = Serde::<( - EthAddress, u256 - )>::deserialize(ref params) + let (evm_contract_address, slot_index) = Serde::< + (EthAddress, u256) + >::deserialize(ref params) .unwrap(); - let (checkpoint_index, checkpoint_mpt_proof, exclusion_mpt_proof) = Serde::<( - u32, Span>, Span> - )>::deserialize(ref user_params) + let (checkpoint_index, checkpoint_mpt_proof, exclusion_mpt_proof) = Serde::< + (u32, Span>, Span>) + >::deserialize(ref user_params) .unwrap(); // Get the slot key for the final checkpoint @@ -77,7 +79,6 @@ mod OZVotesStorageProofVotingStrategy { } } - #[external(v0)] #[generate_trait] impl SingleSlotProofImpl of SingleSlotProofTrait { /// Queries the Timestamp Remapper contract for the closest L1 block number that occured before diff --git a/starknet/src/voting_strategies/oz_votes_trace_208_storage_proof.cairo b/starknet/src/voting_strategies/oz_votes_trace_208_storage_proof.cairo index 7b047d28f..954352780 100644 --- a/starknet/src/voting_strategies/oz_votes_trace_208_storage_proof.cairo +++ b/starknet/src/voting_strategies/oz_votes_trace_208_storage_proof.cairo @@ -10,7 +10,7 @@ mod OZVotesTrace208StorageProofVotingStrategy { #[storage] struct Storage {} - #[external(v0)] + #[abi(embed_v0)] impl OZVotesTrace208StorageProofVotingStrategy of IVotingStrategy { /// Returns the delegated voting power of `voter` at the block number corresponding to `timestamp` for tokens that implement OZVotes with Trace 208 Checkpoints. /// @@ -31,20 +31,22 @@ mod OZVotesTrace208StorageProofVotingStrategy { timestamp: u32, voter: UserAddress, mut params: Span, // [contract_address: address, slot_index: u256] - mut user_params: Span, // [checkpoint_index: u32, checkpoint_mpt_proof: u64[][], exclusion_mpt_proof: u64[][]] + mut user_params: Span< + felt252 + >, // [checkpoint_index: u32, checkpoint_mpt_proof: u64[][], exclusion_mpt_proof: u64[][]] ) -> u256 { // Cast voter address to an Ethereum address // Will revert if the address is not a valid Ethereum address let voter = voter.to_ethereum_address(); // Decode params and user_params - let (evm_contract_address, slot_index) = Serde::<( - EthAddress, u256 - )>::deserialize(ref params) + let (evm_contract_address, slot_index) = Serde::< + (EthAddress, u256) + >::deserialize(ref params) .unwrap(); - let (checkpoint_index, checkpoint_mpt_proof, exclusion_mpt_proof) = Serde::<( - u32, Span>, Span> - )>::deserialize(ref user_params) + let (checkpoint_index, checkpoint_mpt_proof, exclusion_mpt_proof) = Serde::< + (u32, Span>, Span>) + >::deserialize(ref user_params) .unwrap(); // Get the slot key for the final checkpoint @@ -77,7 +79,6 @@ mod OZVotesTrace208StorageProofVotingStrategy { } } - #[external(v0)] #[generate_trait] impl SingleSlotProofImpl of SingleSlotProofTrait { /// Queries the Timestamp Remapper contract for the closest L1 block number that occured before diff --git a/tests/stark-sig-auth.test.ts b/tests/stark-sig-auth.test.ts index 548428ea0..9e7a757fe 100644 --- a/tests/stark-sig-auth.test.ts +++ b/tests/stark-sig-auth.test.ts @@ -34,6 +34,7 @@ describe('Starknet Signature Authenticator', function () { let domain: any; before(async function () { + console.log('account address:', account_address, 'account pk:', account_pk); account = await starknet.OpenZeppelinAccount.getAccountFromAddress(account_address, account_pk); const accountFactory = await starknet.getContractFactory('openzeppelin_Account'); const starkSigAuthenticatorFactory = await starknet.getContractFactory( @@ -54,7 +55,7 @@ describe('Starknet Signature Authenticator', function () { await account.declare(vanillaVotingStrategyFactory); await account.declare(vanillaProposalValidationStrategyFactory); await account.declare(spaceFactory); - } catch {} + } catch { } const accountObj = await account.deploy(accountFactory, { _public_key: account_public_key,