From 2a5601ae2738fe068ebf47187e5048ab2c268fa9 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Mon, 21 Nov 2022 20:14:50 +0100 Subject: [PATCH 1/8] remove cairo_contracts --- .gitmodules | 3 --- lib/cairo_contracts | 1 - 2 files changed, 4 deletions(-) delete mode 160000 lib/cairo_contracts diff --git a/.gitmodules b/.gitmodules index 661aca04..928dfe74 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "bal7hazar_contracts"] url = https://github.com/Bal7hazar/cairo-contracts.git path = lib/bal7hazar_contracts -[submodule "cairo_contracts"] - path = lib/cairo_contracts - url = https://github.com/OpenZeppelin/cairo-contracts diff --git a/lib/cairo_contracts b/lib/cairo_contracts deleted file mode 160000 index a9894b4e..00000000 --- a/lib/cairo_contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a9894b4e5cd59efb63757e846c603a5c64b6b44a From 9f28593a1c578b0fbef248ae31f6423dfbf52c7a Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Mon, 21 Nov 2022 20:15:30 +0100 Subject: [PATCH 2/8] add cairo_contracts --- .gitmodules | 3 +++ lib/cairo_contracts | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/cairo_contracts diff --git a/.gitmodules b/.gitmodules index 928dfe74..661aca04 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "bal7hazar_contracts"] url = https://github.com/Bal7hazar/cairo-contracts.git path = lib/bal7hazar_contracts +[submodule "cairo_contracts"] + path = lib/cairo_contracts + url = https://github.com/OpenZeppelin/cairo-contracts diff --git a/lib/cairo_contracts b/lib/cairo_contracts new file mode 160000 index 00000000..20a200d0 --- /dev/null +++ b/lib/cairo_contracts @@ -0,0 +1 @@ +Subproject commit 20a200d084dfafcee173ce047dc22a639f21f3c3 From 144dd37d688bf39fb0c519b62463a54eb260a952 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Wed, 23 Nov 2022 15:02:40 +0100 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8=20add=20proxy=20+=20update=20test?= =?UTF-8?q?s=20accordingly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + protostar.toml | 10 +++-- scripts/configs/testnet.config | 2 +- scripts/starknet.sh | 2 +- src/farm/library.cairo | 10 ++--- src/farm/offseter.cairo | 51 +++++++++++++++++++-- src/farm/yielder.cairo | 51 +++++++++++++++++++-- src/mint/library.cairo | 12 ++--- src/mint/minter.cairo | 54 +++++++++++++++++++--- src/project/project.cairo | 54 +++++++++++++++++++--- src/proxy/proxy.cairo | 5 +++ tests/config.yml | 6 ++- tests/integrations/minter/library.cairo | 55 +++++++++++++++-------- tests/integrations/offseter/library.cairo | 44 +++++++++++------- tests/integrations/project/library.cairo | 27 ++++++----- tests/integrations/yielder/library.cairo | 44 +++++++++++------- 16 files changed, 334 insertions(+), 94 deletions(-) create mode 100644 src/proxy/proxy.cairo diff --git a/.gitignore b/.gitignore index f95c7b99..b65af519 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Python __pycache__ env +.env # starknet node.json diff --git a/protostar.toml b/protostar.toml index d72a57fc..2faa4b4f 100644 --- a/protostar.toml +++ b/protostar.toml @@ -9,15 +9,19 @@ CarbonableProject = ["src/project/project.cairo"] CarbonableMinter = ["src/mint/minter.cairo"] CarbonableYielder = ["src/farm/yielder.cairo"] CarbonableOffseter = ["src/farm/offseter.cairo"] +CarbonableProxy = ["src/proxy/proxy.cairo"] [test] target = ["tests"] -[profile.devnet.deploy] +[profile.devnet.project] gateway-url = "http://127.0.0.1:5050/" -[profile.testnet.deploy] +[profile.testnet.project] network = "testnet" +private-key-path = "./.env" +account-address = "0x063675fa1ecea10063722e61557ed7f49ed2503d6cdd74f4b31e9770b473650c" +max-fee = "auto" -[profile.mainnet.deploy] +[profile.mainnet.project] network = "mainnet" diff --git a/scripts/configs/testnet.config b/scripts/configs/testnet.config index e2fb1fe9..278baa88 100644 --- a/scripts/configs/testnet.config +++ b/scripts/configs/testnet.config @@ -4,7 +4,7 @@ WALLET=starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount # ERC-1155 settings ERC1155_URI="ipfs://bafybeid3s2i3rjqdxeaoi2du7r3yev4n25uzbwla7nyj5v22rwdl7lfvz4" -ERC1155_NAME="Carbonable ERC-1155 Test" +ERC1155_NAME="ERC-1155 Test" # ERC-721 settings ERC721_NAME="Carbonable ERC-721 Test" diff --git a/scripts/starknet.sh b/scripts/starknet.sh index d4c38b79..11c0ebb7 100755 --- a/scripts/starknet.sh +++ b/scripts/starknet.sh @@ -15,7 +15,7 @@ get_account_address() { get_network() { profile=$1 protostar_toml_file=$2 - network=$(grep profile.$profile $protostar_toml_file -A3 -m1 | sed -n 's@^.*[network=|gateway_url=]"\(.*\)".*$@\1@p') + network=$(grep profile.$profile $protostar_toml_file -A3 -m1 | sed -n 's@^.*[network =|gateway_url =]"\(.*\)".*$@\1@p') echo $(get_legacy_network "$network") } diff --git a/src/farm/library.cairo b/src/farm/library.cairo index b6b1879c..f1590bbc 100644 --- a/src/farm/library.cairo +++ b/src/farm/library.cairo @@ -162,7 +162,7 @@ namespace CarbonableFarmer { let (contract_address) = get_contract_address(); let (carbonable_project_address) = carbonable_project_address_.read(); // [Check] Throws error if unknown token id - let (owner) = IERC721.ownerOf( + let (owner) = IERC721.ownerOf( contract_address=carbonable_project_address, tokenId=token_id ); with_attr error_message("CarbonableFarmer: token_id has not been registred") { @@ -223,7 +223,7 @@ namespace CarbonableFarmer { alloc_locals; // [Security] Start reetrancy guard - ReentrancyGuard._start(); + ReentrancyGuard.start(); // [Check] Locked status let (status) = is_locked(); @@ -259,7 +259,7 @@ namespace CarbonableFarmer { registration_.write(token_id, caller); // [Security] End reetrancy guard - ReentrancyGuard._end(); + ReentrancyGuard.end(); return (success=TRUE,); } @@ -270,7 +270,7 @@ namespace CarbonableFarmer { alloc_locals; // [Security] Start reetrancy guard - ReentrancyGuard._start(); + ReentrancyGuard.start(); // [Check] Locked status let (status) = is_locked(); @@ -306,7 +306,7 @@ namespace CarbonableFarmer { } // [Security] End reetrancy guard - ReentrancyGuard._end(); + ReentrancyGuard.end(); return (success=TRUE,); } diff --git a/src/farm/offseter.cairo b/src/farm/offseter.cairo index 6749a5e3..b44488c2 100644 --- a/src/farm/offseter.cairo +++ b/src/farm/offseter.cairo @@ -8,17 +8,18 @@ from starkware.cairo.common.uint256 import Uint256 // Project dependencies from openzeppelin.access.ownable.library import Ownable +from openzeppelin.upgrades.library import Proxy // Local dependencies from src.farm.library import CarbonableFarmer // -// Constructor +// Initializer // -@constructor -func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - carbonable_project_address: felt, owner: felt +@external +func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + carbonable_project_address: felt, owner: felt, proxy_admin: felt ) { // Desc: // Initialize the contract with the given parameters - @@ -30,10 +31,52 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr // Explicit args: // carbonable_project_address(felt): Address of the corresponding Carbonable project // owner(felt): Owner address + // proxy_admin(felt): Admin address // Returns: // None CarbonableFarmer.initializer(carbonable_project_address); Ownable.initializer(owner); + Proxy.initializer(proxy_admin); + return (); +} + +@view +func getImplementationHash{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + implementation: felt +) { + return Proxy.get_implementation_hash(); +} + +@view +func getAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (admin: felt) { + return Proxy.get_admin(); +} + +@external +func upgrade{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + new_implementation: felt +) { + // Desc: + // Renounce ownership + // Implicit args: + // syscall_ptr(felt*) + // pedersen_ptr(HashBuiltin*) + // range_check_ptr + // Returns: + // None + // Explicit args: + // new_implementation(felt): new contract implementation + // Raises: + // caller: caller is not a contract admin + Proxy.assert_only_admin(); + Proxy._set_implementation_hash(new_implementation); + return (); +} + +@external +func setAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(new_admin: felt) { + Proxy.assert_only_admin(); + Proxy._set_admin(new_admin); return (); } diff --git a/src/farm/yielder.cairo b/src/farm/yielder.cairo index 650c79d6..01eb75db 100644 --- a/src/farm/yielder.cairo +++ b/src/farm/yielder.cairo @@ -8,17 +8,18 @@ from starkware.cairo.common.uint256 import Uint256 // Project dependencies from openzeppelin.access.ownable.library import Ownable +from openzeppelin.upgrades.library import Proxy // Local dependencies from src.farm.library import CarbonableFarmer // -// Constructor +// Initializer // -@constructor -func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - carbonable_project_address: felt, owner: felt +@external +func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + carbonable_project_address: felt, owner: felt, proxy_admin: felt ) { // Desc: // Initialize the contract with the given parameters - @@ -30,10 +31,52 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr // Explicit args: // carbonable_project_address(felt): Address of the corresponding Carbonable project // owner(felt): Owner address + // proxy_admin(felt): Admin address // Returns: // None CarbonableFarmer.initializer(carbonable_project_address); Ownable.initializer(owner); + Proxy.initializer(proxy_admin); + return (); +} + +@view +func getImplementationHash{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + implementation: felt +) { + return Proxy.get_implementation_hash(); +} + +@view +func getAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (admin: felt) { + return Proxy.get_admin(); +} + +@external +func upgrade{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + new_implementation: felt +) { + // Desc: + // Renounce ownership + // Implicit args: + // syscall_ptr(felt*) + // pedersen_ptr(HashBuiltin*) + // range_check_ptr + // Returns: + // None + // Explicit args: + // new_implementation(felt): new contract implementation + // Raises: + // caller: caller is not a contract admin + Proxy.assert_only_admin(); + Proxy._set_implementation_hash(new_implementation); + return (); +} + +@external +func setAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(new_admin: felt) { + Proxy.assert_only_admin(); + Proxy._set_admin(new_admin); return (); } diff --git a/src/mint/library.cairo b/src/mint/library.cairo index 4452c844..74c4f61f 100644 --- a/src/mint/library.cairo +++ b/src/mint/library.cairo @@ -261,7 +261,7 @@ namespace CarbonableMinter { alloc_locals; // [Security] Start reetrancy guard - ReentrancyGuard._start(); + ReentrancyGuard.start(); // [Check] Not zero address let (caller) = get_caller_address(); @@ -298,7 +298,7 @@ namespace CarbonableMinter { mint_iter(carbonable_project_address, to, starting_index, quantity_uint256); // [Security] End reetrancy guard - ReentrancyGuard._end(); + ReentrancyGuard.end(); return (TRUE,); } @@ -352,7 +352,7 @@ namespace CarbonableMinter { alloc_locals; // [Security] Start reetrancy guard - ReentrancyGuard._start(); + ReentrancyGuard.start(); // [Check] Whitelisted sale is open let (is_whitelist_open) = whitelisted_sale_open(); @@ -385,7 +385,7 @@ namespace CarbonableMinter { let (success) = buy(quantity); // [Security] End reetrancy guard - ReentrancyGuard._end(); + ReentrancyGuard.end(); return (success,); } @@ -394,7 +394,7 @@ namespace CarbonableMinter { quantity: felt ) -> (success: felt) { // [Security] Start reetrancy guard - ReentrancyGuard._start(); + ReentrancyGuard.start(); // [Check] if at least whitelisted or public sale is open let (public_sale_open) = public_sale_open_.read(); @@ -406,7 +406,7 @@ namespace CarbonableMinter { let (success) = buy(quantity); // [Security] End reetrancy guard - ReentrancyGuard._end(); + ReentrancyGuard.end(); return (success,); } diff --git a/src/mint/minter.cairo b/src/mint/minter.cairo index 93493dd2..ac16100d 100644 --- a/src/mint/minter.cairo +++ b/src/mint/minter.cairo @@ -8,17 +8,17 @@ from starkware.cairo.common.uint256 import Uint256 // Project dependencies from openzeppelin.access.ownable.library import Ownable +from openzeppelin.upgrades.library import Proxy // Local dependencies from src.mint.library import CarbonableMinter // -// Constructor +// Initializer // -@constructor -func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - owner: felt, +@external +func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( carbonable_project_address: felt, payment_token_address: felt, public_sale_open: felt, @@ -26,6 +26,8 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr unit_price: Uint256, max_supply_for_mint: Uint256, reserved_supply_for_mint: Uint256, + owner: felt, + proxy_admin: felt, ) { // Desc: // Initialize the contract with the given parameters - @@ -35,7 +37,6 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr // pedersen_ptr(HashBuiltin*) // range_check_ptr // Explicit args: - // owner(felt): Owner address // carbonable_project_address(felt): Address of the corresponding Carbonable project // payment_token_address(felt): Address of the ERC20 token that will be used during sales // public_sale_open(felt): 1 to open the public sale right after deployment, 0 otherwise @@ -43,6 +44,8 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr // unit_price(Uint256): Price per token (based on ERC20 token defined as -payment_token_address-) // max_supply_for_mint(Uint256): Max supply available whatever the way to mint // reserved_supply_for_mint(Uint256): Supply reserved to be airdropped + // owner(felt): Owner address + // proxy_admin(felt): Admin address // Returns: // None // Raises: @@ -59,6 +62,47 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr reserved_supply_for_mint, ); Ownable.initializer(owner); + Proxy.initializer(proxy_admin); + return (); +} + +@view +func getImplementationHash{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + implementation: felt +) { + return Proxy.get_implementation_hash(); +} + +@view +func getAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (admin: felt) { + return Proxy.get_admin(); +} + +@external +func upgrade{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + new_implementation: felt +) { + // Desc: + // Renounce ownership + // Implicit args: + // syscall_ptr(felt*) + // pedersen_ptr(HashBuiltin*) + // range_check_ptr + // Returns: + // None + // Explicit args: + // new_implementation(felt): new contract implementation + // Raises: + // caller: caller is not a contract admin + Proxy.assert_only_admin(); + Proxy._set_implementation_hash(new_implementation); + return (); +} + +@external +func setAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(new_admin: felt) { + Proxy.assert_only_admin(); + Proxy._set_admin(new_admin); return (); } diff --git a/src/project/project.cairo b/src/project/project.cairo index 16d7c534..6d463ad2 100644 --- a/src/project/project.cairo +++ b/src/project/project.cairo @@ -12,21 +12,23 @@ from openzeppelin.access.ownable.library import Ownable from openzeppelin.introspection.erc165.library import ERC165 from openzeppelin.token.erc721.library import ERC721 from openzeppelin.token.erc721.enumerable.library import ERC721Enumerable +from openzeppelin.upgrades.library import Proxy // Local dependencies from src.project.library import CarbonableProject // -// Constructor +// Initializer // -@constructor -func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - name: felt, symbol: felt, owner: felt +@external +func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + name: felt, symbol: felt, owner: felt, proxy_admin: felt ) { // Desc: // Initialize the contract with the given name, symbol and owner - - // This constructor uses the standard OZ ERC721 initializer, + // This constructor uses the standard OZ Proxy initializer, + // the standard OZ ERC721 initializer, // the standard OZ ERC721Enumerable initializer and // the OZ Ownable initializer // Implicit args: @@ -37,11 +39,53 @@ func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr // name(felt): Name of the collection // symbol(felt): Symbol of the collection // owner(felt): Owner address + // proxy_admin(felt): Admin address // Returns: // None ERC721.initializer(name, symbol); ERC721Enumerable.initializer(); Ownable.initializer(owner); + Proxy.initializer(proxy_admin); + return (); +} + +@view +func getImplementationHash{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + implementation: felt +) { + return Proxy.get_implementation_hash(); +} + +@view +func getAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (admin: felt) { + return Proxy.get_admin(); +} + +@external +func upgrade{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + new_implementation: felt +) { + // Desc: + // Renounce ownership + // Implicit args: + // syscall_ptr(felt*) + // pedersen_ptr(HashBuiltin*) + // range_check_ptr + // Returns: + // None + // Explicit args: + // new_implementation(felt): new contract implementation + // Raises: + // caller: caller is not a contract admin + Proxy.assert_only_admin(); + Proxy._set_implementation_hash(new_implementation); + return (); +} + +@external +func setAdmin{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(new_admin: felt) { + Proxy.assert_only_admin(); + Proxy._set_admin(new_admin); return (); } diff --git a/src/proxy/proxy.cairo b/src/proxy/proxy.cairo new file mode 100644 index 00000000..e849bb4c --- /dev/null +++ b/src/proxy/proxy.cairo @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT + +%lang starknet + +from openzeppelin.upgrades.presets.Proxy import constructor, __default__ diff --git a/tests/config.yml b/tests/config.yml index 94f6abf8..f1d84bd5 100644 --- a/tests/config.yml +++ b/tests/config.yml @@ -3,10 +3,14 @@ signers: anyone: 1001 sources: + proxy: ./src/proxy/proxy.cairo badge: ./src/badge/badge.cairo project: ./src/project/project.cairo token: ./tests/mocks/erc20.cairo account: ./tests/mocks/account.cairo minter: ./src/mint/minter.cairo yielder: ./src/farm/yielder.cairo - offseter: ./src/farm/offseter.cairo \ No newline at end of file + offseter: ./src/farm/offseter.cairo + +selector: + initializer: 1295919550572838631247819983596733806859788957403169325509326258146877103642 \ No newline at end of file diff --git a/tests/integrations/minter/library.cairo b/tests/integrations/minter/library.cairo index 64efcf19..3dca1c2c 100644 --- a/tests/integrations/minter/library.cairo +++ b/tests/integrations/minter/library.cairo @@ -34,19 +34,26 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { load("./tests/integrations/minter/config.yml", context) # Carbonable project deployment + context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash + calldata = { + "name": context.project.name, + "symbol": context.project.symbol, + "owner": context.signers.admin, + "proxy_admin": context.signers.admin, + } context.carbonable_project_contract = deploy_contract( - context.sources.project, - { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.signers.admin, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_project_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address # Payment token deployment context.payment_token_contract = deploy_contract( - context.sources.token, - { + contract=context.sources.token, + constructor_args={ "name": context.token.name, "symbol": context.token.symbol, "decimals": context.token.decimals, @@ -56,18 +63,28 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { ).contract_address # Carbonable minter deployment + context.carbonable_minter_class_hash = declare(contract=context.sources.minter).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "payment_token_address": context.payment_token_contract, + "public_sale_open": context.minter.public_sale_open, + "max_buy_per_tx": context.minter.max_buy_per_tx, + "unit_price_low": context.minter.unit_price, + "unit_price_high": 0, + "max_supply_for_mint_low": context.minter.max_supply_for_mint, + "max_supply_for_mint_high": 0, + "reserved_supply_for_mint_low": context.minter.reserved_supply_for_mint, + "reserved_supply_for_mint_high": 0, + "owner": context.signers.admin, + "proxy_admin": context.signers.admin, + } context.carbonable_minter_contract = deploy_contract( - context.sources.minter, - { - "owner": context.signers.admin, - "carbonable_project_address": context.carbonable_project_contract, - "payment_token_address": context.payment_token_contract, - "public_sale_open": context.minter.public_sale_open, - "max_buy_per_tx": context.minter.max_buy_per_tx, - "unit_price": context.minter.unit_price, - "max_supply_for_mint": context.minter.max_supply_for_mint, - "reserved_supply_for_mint": context.minter.reserved_supply_for_mint, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_minter_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address # Externalize required variables diff --git a/tests/integrations/offseter/library.cairo b/tests/integrations/offseter/library.cairo index 767325c2..0c8eb759 100644 --- a/tests/integrations/offseter/library.cairo +++ b/tests/integrations/offseter/library.cairo @@ -33,37 +33,51 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { # Admin account deployment context.admin_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.admin, }, ).contract_address # Anyone account deployment context.anyone_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.anyone, }, ).contract_address # Carbonable project deployment + context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash + calldata = { + "name": context.project.name, + "symbol": context.project.symbol, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } context.carbonable_project_contract = deploy_contract( - context.sources.project, - { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.admin_account_contract, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_project_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address # Carbonable offseter deployment + context.carbonable_offseter_class_hash = declare(contract=context.sources.offseter).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } context.carbonable_offseter_contract = deploy_contract( - context.sources.offseter, - { - "owner": context.admin_account_contract, - "carbonable_project_address": context.carbonable_project_contract, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_offseter_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address %} diff --git a/tests/integrations/project/library.cairo b/tests/integrations/project/library.cairo index e4efdd21..9780e429 100644 --- a/tests/integrations/project/library.cairo +++ b/tests/integrations/project/library.cairo @@ -28,28 +28,35 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { # Admin account deployment context.admin_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.admin, }, ).contract_address # Anyone account deployment context.anyone_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.anyone, }, ).contract_address # Carbonable project deployment + context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash + calldata = { + "name": context.project.name, + "symbol": context.project.symbol, + "owner": context.signers.admin, + "proxy_admin": context.signers.admin, + } context.carbonable_project_contract = deploy_contract( - context.sources.project, - { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.admin_account_contract, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_project_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address %} diff --git a/tests/integrations/yielder/library.cairo b/tests/integrations/yielder/library.cairo index d4e499af..d305ece5 100644 --- a/tests/integrations/yielder/library.cairo +++ b/tests/integrations/yielder/library.cairo @@ -33,37 +33,51 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { # Admin account deployment context.admin_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.admin, }, ).contract_address # Anyone account deployment context.anyone_account_contract = deploy_contract( - context.sources.account, - { + contract=context.sources.account, + constructor_args={ "public_key": context.signers.anyone, }, ).contract_address # Carbonable project deployment + context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash + calldata = { + "name": context.project.name, + "symbol": context.project.symbol, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } context.carbonable_project_contract = deploy_contract( - context.sources.project, - { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.admin_account_contract, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_project_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address # Carbonable yielder deployment + context.carbonable_yielder_class_hash = declare(contract=context.sources.yielder).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } context.carbonable_yielder_contract = deploy_contract( - context.sources.yielder, - { - "owner": context.admin_account_contract, - "carbonable_project_address": context.carbonable_project_contract, - }, + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_yielder_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } ).contract_address %} From 81f841c000c7f6059a3ebefcffbc064f10e1d272 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Wed, 23 Nov 2022 20:28:59 +0100 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9C=A8=20add=20access=20control=20to=20m?= =?UTF-8?q?int?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interfaces/project.cairo | 2 +- src/project/project.cairo | 12 ++++++++++- src/utils/access/library.cairo | 26 +++++++++++++++++++++++ tests/integrations/minter/library.cairo | 16 ++++++-------- tests/integrations/offseter/library.cairo | 20 +++++++++++++++++ tests/integrations/yielder/library.cairo | 20 +++++++++++++++++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 src/utils/access/library.cairo diff --git a/src/interfaces/project.cairo b/src/interfaces/project.cairo index dcc1d21f..0ab42cad 100644 --- a/src/interfaces/project.cairo +++ b/src/interfaces/project.cairo @@ -10,7 +10,7 @@ namespace ICarbonableProject { func owner() -> (owner: felt) { } - func transferOwnership(newOwner: felt) { + func set_minter(minter: felt) { } func mint(to: felt, token_id: Uint256) { diff --git a/src/project/project.cairo b/src/project/project.cairo index 6d463ad2..41a949bc 100644 --- a/src/project/project.cairo +++ b/src/project/project.cairo @@ -8,6 +8,7 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin from starkware.cairo.common.uint256 import Uint256 // Project dependencies +from openzeppelin.access.accesscontrol.library import AccessControl from openzeppelin.access.ownable.library import Ownable from openzeppelin.introspection.erc165.library import ERC165 from openzeppelin.token.erc721.library import ERC721 @@ -16,6 +17,7 @@ from openzeppelin.upgrades.library import Proxy // Local dependencies from src.project.library import CarbonableProject +from src.utils.access.library import CarbonableAccessControl // // Initializer @@ -45,6 +47,7 @@ func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr ERC721.initializer(name, symbol); ERC721Enumerable.initializer(); Ownable.initializer(owner); + CarbonableAccessControl.initializer(); Proxy.initializer(proxy_admin); return (); } @@ -324,6 +327,13 @@ func owner{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> // Externals // +@external +func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { + Ownable.assert_only_owner(); + CarbonableAccessControl.set_minter(minter); + return (); +} + @external func approve{pedersen_ptr: HashBuiltin*, syscall_ptr: felt*, range_check_ptr}( to: felt, tokenId: Uint256 @@ -429,7 +439,7 @@ func mint{pedersen_ptr: HashBuiltin*, syscall_ptr: felt*, range_check_ptr}( // to: to is the zero address // tokenId: tokenId is not a valid Uint256 // tokenId: token already minted - Ownable.assert_only_owner(); + CarbonableAccessControl.assert_only_minter(); ERC721Enumerable._mint(to, tokenId); return (); } diff --git a/src/utils/access/library.cairo b/src/utils/access/library.cairo new file mode 100644 index 00000000..6a965c01 --- /dev/null +++ b/src/utils/access/library.cairo @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT + +%lang starknet + +from starkware.cairo.common.cairo_builtins import HashBuiltin + +from openzeppelin.access.accesscontrol.library import AccessControl + +const MINTER_ROLE = 'MINTER'; + +namespace CarbonableAccessControl { + func initializer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + AccessControl.initializer(); + return (); + } + + func assert_only_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + AccessControl.assert_only_role(MINTER_ROLE); + return (); + } + + func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(user: felt) { + AccessControl._grant_role(MINTER_ROLE, user); + return (); + } +} diff --git a/tests/integrations/minter/library.cairo b/tests/integrations/minter/library.cairo index 3dca1c2c..615673f2 100644 --- a/tests/integrations/minter/library.cairo +++ b/tests/integrations/minter/library.cairo @@ -93,7 +93,7 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { %} // Transfer project ownership from admin to minter - admin_instance.transferOwnership(carbonable_minter); + admin_instance.set_minter(carbonable_minter); // Set merkle tree root to minter contract admin_instance.set_whitelist_merkle_root(merkle_root); @@ -134,11 +134,11 @@ namespace carbonable_project_instance { // Externals - func transferOwnership{ + func set_minter{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(newOwner: felt, caller: felt) { + }(minter: felt, caller: felt) { %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.transferOwnership(carbonable_project, newOwner); + ICarbonableProject.set_minter(carbonable_project, minter); %{ stop_prank() %} return (); } @@ -464,15 +464,11 @@ namespace admin_instance { return (); } - func transferOwnership{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - newOwner: felt - ) { + func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { let (carbonable_project) = carbonable_project_instance.deployed(); let (caller) = get_address(); with carbonable_project { - carbonable_project_instance.transferOwnership(newOwner=newOwner, caller=caller); - let (owner) = carbonable_project_instance.owner(); - assert owner = newOwner; + carbonable_project_instance.set_minter(minter=minter, caller=caller); } return (); } diff --git a/tests/integrations/offseter/library.cairo b/tests/integrations/offseter/library.cairo index 0c8eb759..111abaa9 100644 --- a/tests/integrations/offseter/library.cairo +++ b/tests/integrations/offseter/library.cairo @@ -85,6 +85,8 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { let (local admin_address) = admin_instance.get_address(); let (local anyone_address) = anyone_instance.get_address(); + admin_instance.set_minter(admin_address); + admin_instance.mint(to=admin_address, token_id=1); admin_instance.mint(to=admin_address, token_id=2); admin_instance.mint(to=anyone_address, token_id=3); @@ -134,6 +136,15 @@ namespace carbonable_project_instance { // Externals + func set_minter{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(minter: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} + ICarbonableProject.set_minter(carbonable_project, minter); + %{ stop_prank() %} + return (); + } + func approve{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt }(approved: felt, token_id: Uint256, caller: felt) { @@ -325,6 +336,15 @@ namespace admin_instance { // Externals + func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { + let (carbonable_project) = carbonable_project_instance.deployed(); + let (caller) = get_address(); + with carbonable_project { + carbonable_project_instance.set_minter(minter=minter, caller=caller); + } + return (); + } + func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( approved: felt, token_id: felt ) { diff --git a/tests/integrations/yielder/library.cairo b/tests/integrations/yielder/library.cairo index d305ece5..48cba6f4 100644 --- a/tests/integrations/yielder/library.cairo +++ b/tests/integrations/yielder/library.cairo @@ -85,6 +85,8 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { let (local admin_address) = admin_instance.get_address(); let (local anyone_address) = anyone_instance.get_address(); + admin_instance.set_minter(admin_address); + admin_instance.mint(to=admin_address, token_id=1); admin_instance.mint(to=admin_address, token_id=2); admin_instance.mint(to=anyone_address, token_id=3); @@ -134,6 +136,15 @@ namespace carbonable_project_instance { // Externals + func set_minter{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(minter: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} + ICarbonableProject.set_minter(carbonable_project, minter); + %{ stop_prank() %} + return (); + } + func approve{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt }(approved: felt, token_id: Uint256, caller: felt) { @@ -337,6 +348,15 @@ namespace admin_instance { // Externals + func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { + let (carbonable_project) = carbonable_project_instance.deployed(); + let (caller) = get_address(); + with carbonable_project { + carbonable_project_instance.set_minter(minter=minter, caller=caller); + } + return (); + } + func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( approved: felt, token_id: felt ) { From 299895b9c6574641999bae7abea6b0a237e62fe4 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Thu, 24 Nov 2022 13:52:26 +0100 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9C=85=20upgrade=20protostar,=20update?= =?UTF-8?q?=20test=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy_badge.yml | 2 +- .github/workflows/deploy_minter.yml | 2 +- .github/workflows/deploy_project.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/transfer_ownership.yml | 2 +- protostar.toml | 4 +- tests/integrations/config.yml | 9 +- tests/integrations/minter/config.yml | 7 - tests/integrations/minter/library.cairo | 307 +--- ..._nominal_cases.cairo => test_minter.cairo} | 18 +- tests/integrations/offseter/library.cairo | 592 ------- tests/integrations/project/library.cairo | 84 - .../project/test_nominal_cases.cairo | 30 - tests/integrations/protocol/library.cairo | 1527 +++++++++++++++++ .../test_offseter.cairo} | 117 +- .../test_yielder.cairo} | 118 +- tests/integrations/yielder/library.cairo | 606 ------- 17 files changed, 1707 insertions(+), 1722 deletions(-) rename tests/integrations/minter/{test_nominal_cases.cairo => test_minter.cairo} (91%) delete mode 100644 tests/integrations/offseter/library.cairo delete mode 100644 tests/integrations/project/library.cairo delete mode 100644 tests/integrations/project/test_nominal_cases.cairo create mode 100644 tests/integrations/protocol/library.cairo rename tests/integrations/{offseter/test_nominal_cases.cairo => protocol/test_offseter.cairo} (62%) rename tests/integrations/{yielder/test_nominal_cases.cairo => protocol/test_yielder.cairo} (61%) delete mode 100644 tests/integrations/yielder/library.cairo diff --git a/.github/workflows/deploy_badge.yml b/.github/workflows/deploy_badge.yml index 2b58e4cb..2cb25e6e 100644 --- a/.github/workflows/deploy_badge.yml +++ b/.github/workflows/deploy_badge.yml @@ -71,7 +71,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableBadge.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.7.0 + PROTOSTAR_VERSION: 0.8.0 jobs: deploy: diff --git a/.github/workflows/deploy_minter.yml b/.github/workflows/deploy_minter.yml index 9d3c0010..243e11bb 100644 --- a/.github/workflows/deploy_minter.yml +++ b/.github/workflows/deploy_minter.yml @@ -121,7 +121,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableMinter.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.7.0 + PROTOSTAR_VERSION: 0.8.0 jobs: deploy: diff --git a/.github/workflows/deploy_project.yml b/.github/workflows/deploy_project.yml index 32e2736d..284b4297 100644 --- a/.github/workflows/deploy_project.yml +++ b/.github/workflows/deploy_project.yml @@ -72,7 +72,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableProject.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.7.0 + PROTOSTAR_VERSION: 0.8.0 jobs: deploy: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 590d7ecb..75e4871a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ name: CI Tests on: [push, pull_request, pull_request_target] env: - PROTOSTAR_VERSION: 0.7.0 + PROTOSTAR_VERSION: 0.8.0 jobs: protostar-tests: diff --git a/.github/workflows/transfer_ownership.yml b/.github/workflows/transfer_ownership.yml index 3f9a5813..451e2915 100644 --- a/.github/workflows/transfer_ownership.yml +++ b/.github/workflows/transfer_ownership.yml @@ -73,7 +73,7 @@ permissions: env: PROJECT_ABI: ./build/CarbonableProject_abi.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.7.0 + PROTOSTAR_VERSION: 0.8.0 jobs: transfer: diff --git a/protostar.toml b/protostar.toml index 2faa4b4f..4a2ad077 100644 --- a/protostar.toml +++ b/protostar.toml @@ -1,5 +1,5 @@ [project] -protostar-version = "0.7.0" +protostar-version = "0.8.0" lib-path = "lib" cairo-path = ["./lib/cairopen_contracts/src", "./lib/cairo_contracts/src", "./lib/bal7hazar_contracts/src", "src"] @@ -21,7 +21,7 @@ gateway-url = "http://127.0.0.1:5050/" network = "testnet" private-key-path = "./.env" account-address = "0x063675fa1ecea10063722e61557ed7f49ed2503d6cdd74f4b31e9770b473650c" -max-fee = "auto" +block-explorer = "starkscan" [profile.mainnet.project] network = "mainnet" diff --git a/tests/integrations/config.yml b/tests/integrations/config.yml index b7b8fc97..80ba6a29 100644 --- a/tests/integrations/config.yml +++ b/tests/integrations/config.yml @@ -10,4 +10,11 @@ token: name: Token symbol: TOK decimals: 6 - initial_supply: 1000000 \ No newline at end of file + initial_supply: 1000000 + +minter: + public_sale_open: 0 + max_buy_per_tx: 5 + unit_price: 10 + max_supply_for_mint: 10 + reserved_supply_for_mint: 4 \ No newline at end of file diff --git a/tests/integrations/minter/config.yml b/tests/integrations/minter/config.yml index f00b7f36..a19e8f97 100644 --- a/tests/integrations/minter/config.yml +++ b/tests/integrations/minter/config.yml @@ -1,10 +1,3 @@ -minter: - public_sale_open: 0 - max_buy_per_tx: 5 - unit_price: 10 - max_supply_for_mint: 10 - reserved_supply_for_mint: 4 - whitelist: slots: 5 merkle_root: 3236969588476960619958150604131083087415975923122021901088942336874683133579 diff --git a/tests/integrations/minter/library.cairo b/tests/integrations/minter/library.cairo index 615673f2..0c2e7782 100644 --- a/tests/integrations/minter/library.cairo +++ b/tests/integrations/minter/library.cairo @@ -17,6 +17,11 @@ from openzeppelin.security.safemath.library import SafeUint256 // Local dependencies from interfaces.minter import ICarbonableMinter from interfaces.project import ICarbonableProject +from tests.integrations.protocol.library import ( + carbonable_project_instance, + payment_token_instance, + carbonable_minter_instance, +) // // Functions @@ -24,7 +29,6 @@ from interfaces.project import ICarbonableProject func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { alloc_locals; - local carbonable_minter; local merkle_root; %{ # Load config @@ -88,272 +92,17 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { ).contract_address # Externalize required variables - ids.carbonable_minter = context.carbonable_minter_contract ids.merkle_root = context.whitelist.merkle_root %} - // Transfer project ownership from admin to minter + // Set minter and merkle root + let (local carbonable_minter) = carbonable_minter_instance.get_address(); admin_instance.set_minter(carbonable_minter); - // Set merkle tree root to minter contract admin_instance.set_whitelist_merkle_root(merkle_root); return (); } -namespace carbonable_project_instance { - // Internals - - func deployed() -> (carbonable_project_contract: felt) { - tempvar carbonable_project_contract; - %{ ids.carbonable_project_contract = context.carbonable_project_contract %} - return (carbonable_project_contract,); - } - - // Views - - func owner{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (owner: felt) { - let (owner: felt) = ICarbonableProject.owner(carbonable_project); - return (owner,); - } - - func balanceOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(owner: felt) -> (balance: Uint256) { - let (balance) = IERC721.balanceOf(carbonable_project, owner); - return (balance,); - } - - func totalSupply{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (totalSupply: Uint256) { - let (total_supply) = IERC721Enumerable.totalSupply(carbonable_project); - return (total_supply,); - } - - // Externals - - func set_minter{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(minter: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.set_minter(carbonable_project, minter); - %{ stop_prank() %} - return (); - } -} - -namespace payment_token_instance { - // Internals - - func deployed() -> (payment_token_contract: felt) { - tempvar payment_token_contract; - %{ ids.payment_token_contract = context.payment_token_contract %} - return (payment_token_contract,); - } - - // Views - - func balanceOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt - }(account: felt) -> (balance: Uint256) { - let (balance) = IERC20.balanceOf(payment_token, account); - return (balance,); - } - - func allowance{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt - }(owner: felt, spender: felt) -> (remaining: Uint256) { - let (remaining) = IERC20.allowance(payment_token, owner, spender); - return (remaining,); - } - - // Externals - - func approve{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt - }(spender: felt, amount: Uint256, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(ids.caller, ids.payment_token) %} - let (success) = IERC20.approve(payment_token, spender, amount); - %{ stop_prank() %} - return (success,); - } -} - -namespace carbonable_minter_instance { - // Internals - - func deployed() -> (carbonable_minter_contract: felt) { - tempvar carbonable_minter_contract; - %{ ids.carbonable_minter_contract = context.carbonable_minter_contract %} - return (carbonable_minter_contract,); - } - - // Views - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (carbonable_project_address: felt) { - let (carbonable_project_address) = ICarbonableMinter.carbonable_project_address( - carbonable_minter - ); - return (carbonable_project_address,); - } - - func payment_token_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (payment_token_address: felt) { - let (payment_token_address) = ICarbonableMinter.payment_token_address(carbonable_minter); - return (payment_token_address,); - } - - func whitelisted_sale_open{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (whitelisted_sale_open: felt) { - let (whitelisted_sale_open) = ICarbonableMinter.whitelisted_sale_open(carbonable_minter); - return (whitelisted_sale_open,); - } - - func public_sale_open{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (public_sale_open: felt) { - let (public_sale_open) = ICarbonableMinter.public_sale_open(carbonable_minter); - return (public_sale_open,); - } - - func max_buy_per_tx{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (max_buy_per_tx: felt) { - let (max_buy_per_tx) = ICarbonableMinter.max_buy_per_tx(carbonable_minter); - return (max_buy_per_tx,); - } - - func unit_price{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (unit_price: Uint256) { - let (unit_price) = ICarbonableMinter.unit_price(carbonable_minter); - return (unit_price,); - } - - func max_supply_for_mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (max_supply_for_mint: Uint256) { - let (max_supply_for_mint) = ICarbonableMinter.max_supply_for_mint(carbonable_minter); - return (max_supply_for_mint,); - } - - func reserved_supply_for_mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (reserved_supply_for_mint: Uint256) { - let (reserved_supply_for_mint) = ICarbonableMinter.reserved_supply_for_mint( - carbonable_minter - ); - return (reserved_supply_for_mint,); - } - - func whitelist_merkle_root{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }() -> (whitelist_merkle_root: felt) { - let (whitelist_merkle_root) = ICarbonableMinter.whitelist_merkle_root(carbonable_minter); - return (whitelist_merkle_root,); - } - - func whitelisted_slots{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(account: felt, slots: felt, proof_len: felt, proof: felt*) -> (slots: felt) { - let (slots) = ICarbonableMinter.whitelisted_slots( - carbonable_minter, account, slots, proof_len, proof - ); - return (slots,); - } - - // Externals - - func decrease_reserved_supply_for_mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(slots: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - ICarbonableMinter.decrease_reserved_supply_for_mint(carbonable_minter, slots); - %{ stop_prank() %} - return (); - } - - func withdraw{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - let (success) = ICarbonableMinter.withdraw(carbonable_minter); - %{ stop_prank() %} - return (success,); - } - - func set_whitelist_merkle_root{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(whitelist_merkle_root: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - ICarbonableMinter.set_whitelist_merkle_root(carbonable_minter, whitelist_merkle_root); - %{ stop_prank() %} - return (); - } - - func set_public_sale_open{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(public_sale_open: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - ICarbonableMinter.set_public_sale_open(carbonable_minter, public_sale_open); - %{ stop_prank() %} - return (); - } - - func set_max_buy_per_tx{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(max_buy_per_tx: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - ICarbonableMinter.set_max_buy_per_tx(carbonable_minter, max_buy_per_tx); - %{ stop_prank() %} - return (); - } - - func set_unit_price{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(unit_price: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - ICarbonableMinter.set_unit_price(carbonable_minter, unit_price); - %{ stop_prank() %} - return (); - } - - func whitelist_buy{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(slots: felt, proof_len: felt, proof: felt*, quantity: felt, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - let (success) = ICarbonableMinter.whitelist_buy( - carbonable_minter, slots, proof_len, proof, quantity - ); - %{ stop_prank() %} - return (success,); - } - - func public_buy{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(quantity: felt, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - let (success) = ICarbonableMinter.public_buy(carbonable_minter, quantity); - %{ stop_prank() %} - return (success,); - } - - func airdrop{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt - }(to: felt, quantity: felt, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} - let (success) = ICarbonableMinter.airdrop(carbonable_minter, to, quantity); - %{ stop_prank() %} - return (success,); - } -} - namespace admin_instance { // Internals @@ -366,8 +115,8 @@ namespace admin_instance { // Externals func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_minter) = carbonable_minter_instance.deployed(); - let (payment_token) = payment_token_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); let (caller) = get_address(); with payment_token { let (initial_balance) = payment_token_instance.balanceOf(account=caller); @@ -388,7 +137,7 @@ namespace admin_instance { func set_whitelist_merkle_root{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( whitelist_merkle_root: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); with carbonable_minter { carbonable_minter_instance.set_whitelist_merkle_root( @@ -404,7 +153,7 @@ namespace admin_instance { func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( public_sale_open: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); with carbonable_minter { carbonable_minter_instance.set_public_sale_open( @@ -419,7 +168,7 @@ namespace admin_instance { func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( max_buy_per_tx: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); with carbonable_minter { carbonable_minter_instance.set_max_buy_per_tx( @@ -434,7 +183,7 @@ namespace admin_instance { func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( unit_price: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); let unit_price_uint256 = Uint256(unit_price, 0); with carbonable_minter { @@ -449,7 +198,7 @@ namespace admin_instance { syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }(slots: felt) { alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); let slots_uint256 = Uint256(slots, 0); with carbonable_minter { @@ -465,7 +214,7 @@ namespace admin_instance { } func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { - let (carbonable_project) = carbonable_project_instance.deployed(); + let (carbonable_project) = carbonable_project_instance.get_address(); let (caller) = get_address(); with carbonable_project { carbonable_project_instance.set_minter(minter=minter, caller=caller); @@ -477,8 +226,8 @@ namespace admin_instance { to: felt, quantity: felt ) { alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); let (caller) = get_address(); let quantity_uint256 = Uint256(quantity, 0); @@ -555,7 +304,7 @@ namespace anyone_instance { func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( public_sale_open: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); with carbonable_minter { carbonable_minter_instance.set_public_sale_open( @@ -570,7 +319,7 @@ namespace anyone_instance { func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( max_buy_per_tx: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); with carbonable_minter { carbonable_minter_instance.set_max_buy_per_tx( @@ -585,7 +334,7 @@ namespace anyone_instance { func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( unit_price: felt ) { - let (carbonable_minter) = carbonable_minter_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); let (caller) = get_address(); let unit_price_uint256 = Uint256(unit_price, 0); with carbonable_minter { @@ -598,8 +347,8 @@ namespace anyone_instance { func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(quantity: felt) { alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.deployed(); - let (payment_token) = payment_token_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); let (caller) = get_address(); with carbonable_minter { let (unit_price) = carbonable_minter_instance.unit_price(); @@ -622,9 +371,9 @@ namespace anyone_instance { quantity: felt ) { alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (payment_token) = payment_token_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); let (caller) = get_address(); let (slots) = get_slots(); let (proof_len) = get_proof_len(); @@ -676,9 +425,9 @@ namespace anyone_instance { quantity: felt ) { alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (payment_token) = payment_token_instance.deployed(); + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); let (caller) = get_address(); // get user nft and payment token balances to check after buy diff --git a/tests/integrations/minter/test_nominal_cases.cairo b/tests/integrations/minter/test_minter.cairo similarity index 91% rename from tests/integrations/minter/test_nominal_cases.cairo rename to tests/integrations/minter/test_minter.cairo index 9e6bf6b6..9f4a9795 100644 --- a/tests/integrations/minter/test_nominal_cases.cairo +++ b/tests/integrations/minter/test_minter.cairo @@ -38,7 +38,7 @@ func __setup__{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( } @view -func test_e2e_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { +func test_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { // When anyone approves minter for 5 token equivalent nfts // And anyone makes 5 whitelist buy // And admin open the public sale @@ -58,7 +58,7 @@ func test_e2e_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_ } @view -func test_e2e_not_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { +func test_not_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { // When admin set up a new whitelist merkle tree excluding anyone // And anyone approves minter for 1 token equivalent nft // And anyone makes 1 whitelist buy @@ -73,7 +73,7 @@ func test_e2e_not_whitelisted{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, ra } @view -func test_e2e_airdrop{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { +func test_airdrop{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { // When anyone approves minter for 5 token equivalent nfts // And anyone makes 5 whitelist buy // And admin open the public sale @@ -99,7 +99,7 @@ func test_e2e_airdrop{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_chec } @view -func test_e2e_public_buy_not_enough_available_nfts{ +func test_public_buy_not_enough_available_nfts{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone approves minter for 5 token equivalent nfts @@ -122,7 +122,7 @@ func test_e2e_public_buy_not_enough_available_nfts{ } @view -func test_e2e_airdrop_not_enough_available_reserved_nfts{ +func test_airdrop_not_enough_available_reserved_nfts{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone approves minter for 5 token equivalent nfts @@ -144,7 +144,7 @@ func test_e2e_airdrop_not_enough_available_reserved_nfts{ } @view -func test_e2e_over_airdropped{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { +func test_over_airdropped{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { // When admin airdrops 11 nfts to anyone // Then 'not enough available NFTs' failed transaction happens alloc_locals; @@ -157,7 +157,7 @@ func test_e2e_over_airdropped{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, ra } @view -func test_e2e_revert_set_public_sale_not_owner{ +func test_revert_set_public_sale_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone closes the public sale @@ -171,7 +171,7 @@ func test_e2e_revert_set_public_sale_not_owner{ } @view -func test_e2e_revert_set_max_buy_per_tx_not_owner{ +func test_revert_set_max_buy_per_tx_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone set the max buy per tx @@ -185,7 +185,7 @@ func test_e2e_revert_set_max_buy_per_tx_not_owner{ } @view -func test_e2e_revert_set_unit_price_not_owner{ +func test_revert_set_unit_price_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone set the unit price diff --git a/tests/integrations/offseter/library.cairo b/tests/integrations/offseter/library.cairo deleted file mode 100644 index 111abaa9..00000000 --- a/tests/integrations/offseter/library.cairo +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: MIT - -%lang starknet - -// Starkware dependencies -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.bool import TRUE, FALSE -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.cairo.common.uint256 import Uint256 - -// Project dependencies -from openzeppelin.token.erc20.IERC20 import IERC20 -from openzeppelin.token.erc721.IERC721 import IERC721 -from openzeppelin.token.erc721.enumerable.IERC721Enumerable import IERC721Enumerable -from openzeppelin.security.safemath.library import SafeUint256 - -// Local dependencies -from interfaces.offseter import ICarbonableOffseter -from interfaces.project import ICarbonableProject - -// -// Functions -// - -func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - alloc_locals; - %{ - # Load config - import sys - sys.path.append('.') - from tests import load - load("./tests/integrations/offseter/config.yml", context) - - # Admin account deployment - context.admin_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.admin, - }, - ).contract_address - - # Anyone account deployment - context.anyone_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.anyone, - }, - ).contract_address - - # Carbonable project deployment - context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash - calldata = { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.admin_account_contract, - "proxy_admin": context.admin_account_contract, - } - context.carbonable_project_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_project_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - - # Carbonable offseter deployment - context.carbonable_offseter_class_hash = declare(contract=context.sources.offseter).class_hash - calldata = { - "carbonable_project_address": context.carbonable_project_contract, - "owner": context.admin_account_contract, - "proxy_admin": context.admin_account_contract, - } - context.carbonable_offseter_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_offseter_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - %} - - // Mint 2 tokens to admin and 3 tokens to anyone - let (local admin_address) = admin_instance.get_address(); - let (local anyone_address) = anyone_instance.get_address(); - - admin_instance.set_minter(admin_address); - - admin_instance.mint(to=admin_address, token_id=1); - admin_instance.mint(to=admin_address, token_id=2); - admin_instance.mint(to=anyone_address, token_id=3); - admin_instance.mint(to=anyone_address, token_id=4); - admin_instance.mint(to=anyone_address, token_id=5); - return (); -} - -namespace carbonable_project_instance { - // Internals - - func deployed() -> (carbonable_project_contract: felt) { - tempvar carbonable_project_contract; - %{ ids.carbonable_project_contract = context.carbonable_project_contract %} - return (carbonable_project_contract,); - } - - // Views - - func owner{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (owner: felt) { - let (owner: felt) = ICarbonableProject.owner(carbonable_project); - return (owner,); - } - - func balanceOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(owner: felt) -> (balance: Uint256) { - let (balance) = IERC721.balanceOf(carbonable_project, owner); - return (balance,); - } - - func ownerOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(tokenId: Uint256) -> (owner: felt) { - let (owner) = IERC721.ownerOf(carbonable_project, tokenId); - return (owner,); - } - - func totalSupply{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (totalSupply: Uint256) { - let (total_supply) = IERC721Enumerable.totalSupply(carbonable_project); - return (total_supply,); - } - - // Externals - - func set_minter{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(minter: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.set_minter(carbonable_project, minter); - %{ stop_prank() %} - return (); - } - - func approve{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(approved: felt, token_id: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - IERC721.approve(carbonable_project, approved, token_id); - %{ stop_prank() %} - return (); - } - - func mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(to: felt, token_id: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.mint(carbonable_project, to, token_id); - %{ stop_prank() %} - return (); - } -} - -namespace carbonable_offseter_instance { - // Internals - - func deployed() -> (carbonable_offseter_contract: felt) { - tempvar carbonable_offseter_contract; - %{ ids.carbonable_offseter_contract = context.carbonable_offseter_contract %} - return (carbonable_offseter_contract=carbonable_offseter_contract,); - } - - // Views - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }() -> (carbonable_project_address: felt) { - let (carbonable_project_address) = ICarbonableOffseter.carbonable_project_address( - carbonable_offseter - ); - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }() -> (status: felt) { - let (status) = ICarbonableOffseter.is_locked(carbonable_offseter); - return (status=status,); - } - - func total_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }() -> (balance: Uint256) { - let (balance) = ICarbonableOffseter.total_locked(carbonable_offseter); - return (balance=balance,); - } - - func balance_of{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(address: felt) -> (balance: felt) { - let (balance) = ICarbonableOffseter.balance_of(carbonable_offseter, address); - return (balance=balance,); - } - - func registred_owner_of{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(token_id: Uint256) -> (address: felt) { - let (address) = ICarbonableOffseter.registred_owner_of(carbonable_offseter, token_id); - return (address=address,); - } - - // Externals - - func start_period{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(unlocked_duration: felt, period_duration: felt, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} - let (success) = ICarbonableOffseter.start_period( - carbonable_offseter, unlocked_duration, period_duration - ); - %{ stop_prank() %} - return (success=success,); - } - - func stop_period{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} - let (success) = ICarbonableOffseter.stop_period(carbonable_offseter); - %{ stop_prank() %} - return (success=success,); - } - - func deposit{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { - %{ stop_prank_offseter = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} - %{ stop_prank_project = start_prank(caller_address=ids.carbonable_offseter, target_contract_address=ids.carbonable_project) %} - let (success) = ICarbonableOffseter.deposit(carbonable_offseter, token_id); - %{ stop_prank_offseter() %} - %{ stop_prank_project() %} - return (success=success,); - } - - func withdraw{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt - }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { - %{ stop_prank_offseter = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} - %{ stop_prank_project = start_prank(caller_address=ids.carbonable_offseter, target_contract_address=ids.carbonable_project) %} - let (success) = ICarbonableOffseter.withdraw(carbonable_offseter, token_id); - %{ stop_prank_offseter() %} - %{ stop_prank_project() %} - return (success=success,); - } -} - -namespace admin_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar admin; - %{ ids.admin = context.admin_account_contract %} - return (admin,); - } - - // Views - - func owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (owner: felt) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - } - return (owner=owner,); - } - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr - }() -> (carbonable_project_address: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let ( - carbonable_project_address - ) = carbonable_offseter_instance.carbonable_project_address(); - } - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - status: felt - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (status) = carbonable_offseter_instance.is_locked(); - } - return (status=status,); - } - - func total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - balance: Uint256 - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (balance) = carbonable_offseter_instance.total_locked(); - } - return (balance=balance,); - } - - func balance_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - address: felt - ) -> (balance: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (balance) = carbonable_offseter_instance.balance_of(address=address); - } - return (balance=balance,); - } - - func registred_owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (address: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_offseter { - let (address) = carbonable_offseter_instance.registred_owner_of( - token_id=token_id_uint256 - ); - } - return (address=address,); - } - - // Externals - - func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - with carbonable_project { - carbonable_project_instance.set_minter(minter=minter, caller=caller); - } - return (); - } - - func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - approved: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.approve( - approved=approved, token_id=token_id_uint256, caller=caller - ); - } - return (); - } - - func mint{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - to: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.mint(to=to, token_id=token_id_uint256, caller=caller); - } - return (); - } - - func start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unlocked_duration: felt, period_duration: felt - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (caller) = get_address(); - with carbonable_offseter { - let (success) = carbonable_offseter_instance.start_period( - unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller - ); - assert success = TRUE; - } - return (); - } - - func stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (caller) = get_address(); - with carbonable_offseter { - let (success) = carbonable_offseter_instance.stop_period(caller=caller); - assert success = TRUE; - } - return (); - } - - func deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - with carbonable_offseter { - let (success) = carbonable_offseter_instance.deposit( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_offseter; - } - return (); - } - - func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_offseter; - } - with carbonable_offseter { - let (success) = carbonable_offseter_instance.withdraw( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - return (); - } -} - -namespace anyone_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar anyone; - %{ ids.anyone = context.anyone_account_contract %} - return (anyone,); - } - - // Views - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr - }() -> (carbonable_project_address: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let ( - carbonable_project_address - ) = carbonable_offseter_instance.carbonable_project_address(); - } - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - status: felt - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (status) = carbonable_offseter_instance.is_locked(); - } - return (status=status,); - } - - func total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - balance: Uint256 - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (balance) = carbonable_offseter_instance.total_locked(); - } - return (balance=balance,); - } - - func balance_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - address: felt - ) -> (balance: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - with carbonable_offseter { - let (balance) = carbonable_offseter_instance.balance_of(address=address); - } - return (balance=balance,); - } - - func registred_owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (address: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_offseter { - let (address) = carbonable_offseter_instance.registred_owner_of( - token_id=token_id_uint256 - ); - } - return (address=address,); - } - - // Externals - - func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - approved: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.approve( - approved=approved, token_id=token_id_uint256, caller=caller - ); - } - return (); - } - - func start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unlocked_duration: felt, period_duration: felt - ) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (caller) = get_address(); - with carbonable_offseter { - let (success) = carbonable_offseter_instance.start_period( - unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller - ); - assert success = TRUE; - } - return (); - } - - func stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (caller) = get_address(); - with carbonable_offseter { - let (success) = carbonable_offseter_instance.stop_period(caller=caller); - assert success = TRUE; - } - return (); - } - - func deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - with carbonable_offseter { - let (success) = carbonable_offseter_instance.deposit( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_offseter; - } - return (); - } - - func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_offseter) = carbonable_offseter_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_offseter; - } - with carbonable_offseter { - let (success) = carbonable_offseter_instance.withdraw( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - return (); - } -} diff --git a/tests/integrations/project/library.cairo b/tests/integrations/project/library.cairo deleted file mode 100644 index 9780e429..00000000 --- a/tests/integrations/project/library.cairo +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: MIT - -%lang starknet - -// Starkware dependencies -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.cairo.common.bool import TRUE, FALSE - -// Project dependencies -from cairopen.string.ASCII import StringCodec - -// Local dependencies -from interfaces.project import ICarbonableProject -from tests.library import assert_string - -// -// Functions -// - -func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - %{ - # Load config - import sys - sys.path.append('.') - from tests import load - load("./tests/integrations/project/config.yml", context) - - # Admin account deployment - context.admin_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.admin, - }, - ).contract_address - - # Anyone account deployment - context.anyone_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.anyone, - }, - ).contract_address - - # Carbonable project deployment - context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash - calldata = { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.signers.admin, - "proxy_admin": context.signers.admin, - } - context.carbonable_project_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_project_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - %} - - return (); -} - -namespace carbonable_project_instance { - // Internals - - func deployed() -> (carbonable_project_contract: felt) { - tempvar carbonable_project_contract; - %{ ids.carbonable_project_contract = context.carbonable_project_contract %} - return (carbonable_project_contract,); - } -} - -namespace admin_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar admin; - %{ ids.admin = context.admin_account_contract %} - return (admin,); - } -} diff --git a/tests/integrations/project/test_nominal_cases.cairo b/tests/integrations/project/test_nominal_cases.cairo deleted file mode 100644 index 2acb1be5..00000000 --- a/tests/integrations/project/test_nominal_cases.cairo +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -%lang starknet - -// Starkware dependencies -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.cairo.common.bool import TRUE, FALSE - -// Local dependencies -from tests.integrations.project.library import setup, admin_instance as admin - -@view -func __setup__{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - // Given a deployed user contracts - // And an admin with address 1000 - // And an anyone with address 1001 - // Given a deployed project contact - // And owned by admin - return setup(); -} - -@view -func test_uri{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, bitwise_ptr: BitwiseBuiltin*, range_check_ptr -}() { - // When - - return (); -} diff --git a/tests/integrations/protocol/library.cairo b/tests/integrations/protocol/library.cairo new file mode 100644 index 00000000..41b0b794 --- /dev/null +++ b/tests/integrations/protocol/library.cairo @@ -0,0 +1,1527 @@ +// SPDX-License-Identifier: MIT + +%lang starknet + +// Starkware dependencies +from starkware.cairo.common.alloc import alloc +from starkware.cairo.common.bool import TRUE, FALSE +from starkware.cairo.common.cairo_builtins import HashBuiltin +from starkware.cairo.common.uint256 import Uint256 + +// Project dependencies +from openzeppelin.token.erc20.IERC20 import IERC20 +from openzeppelin.token.erc721.IERC721 import IERC721 +from openzeppelin.token.erc721.enumerable.IERC721Enumerable import IERC721Enumerable +from openzeppelin.security.safemath.library import SafeUint256 + +// Local dependencies +from interfaces.minter import ICarbonableMinter +from interfaces.offseter import ICarbonableOffseter +from interfaces.project import ICarbonableProject +from interfaces.yielder import ICarbonableYielder + +// +// Functions +// + +func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + alloc_locals; + %{ + # Load config + import sys + sys.path.append('.') + from tests import load + load("./tests/integrations/minter/config.yml", context) + + # Admin account deployment + context.admin_account_contract = deploy_contract( + contract=context.sources.account, + constructor_args={ + "public_key": context.signers.admin, + }, + ).contract_address + + # Anyone account deployment + context.anyone_account_contract = deploy_contract( + contract=context.sources.account, + constructor_args={ + "public_key": context.signers.anyone, + }, + ).contract_address + + # Carbonable project deployment + context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash + calldata = { + "name": context.project.name, + "symbol": context.project.symbol, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } + context.carbonable_project_contract = deploy_contract( + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_project_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } + ).contract_address + + # Payment token deployment + context.payment_token_contract = deploy_contract( + contract=context.sources.token, + constructor_args={ + "name": context.token.name, + "symbol": context.token.symbol, + "decimals": context.token.decimals, + "initial_supply": context.token.initial_supply, + "recipient": context.signers.anyone + }, + ).contract_address + + # Carbonable minter deployment + context.carbonable_minter_class_hash = declare(contract=context.sources.minter).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "payment_token_address": context.payment_token_contract, + "public_sale_open": context.minter.public_sale_open, + "max_buy_per_tx": context.minter.max_buy_per_tx, + "unit_price_low": context.minter.unit_price, + "unit_price_high": 0, + "max_supply_for_mint_low": context.minter.max_supply_for_mint, + "max_supply_for_mint_high": 0, + "reserved_supply_for_mint_low": context.minter.reserved_supply_for_mint, + "reserved_supply_for_mint_high": 0, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } + context.carbonable_minter_contract = deploy_contract( + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_minter_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } + ).contract_address + + # Carbonable yielder deployment + context.carbonable_yielder_class_hash = declare(contract=context.sources.yielder).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } + context.carbonable_yielder_contract = deploy_contract( + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_yielder_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } + ).contract_address + + # Carbonable offseter deployment + context.carbonable_offseter_class_hash = declare(contract=context.sources.offseter).class_hash + calldata = { + "carbonable_project_address": context.carbonable_project_contract, + "owner": context.admin_account_contract, + "proxy_admin": context.admin_account_contract, + } + context.carbonable_offseter_contract = deploy_contract( + contract=context.sources.proxy, + constructor_args={ + "implementation_hash": context.carbonable_offseter_class_hash, + "selector": context.selector.initializer, + "calldata": calldata.values(), + } + ).contract_address + %} + + // Set minters + let (local admin_address) = admin_instance.get_address(); + let (local carbonable_minter) = carbonable_minter_instance.get_address(); + admin_instance.set_minter(admin_address); + admin_instance.set_minter(carbonable_minter); + + return (); +} + +namespace carbonable_project_instance { + // Internals + + func get_address() -> (carbonable_project_contract: felt) { + tempvar carbonable_project_contract; + %{ ids.carbonable_project_contract = context.carbonable_project_contract %} + return (carbonable_project_contract,); + } + + // Views + + func owner{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }() -> (owner: felt) { + let (owner: felt) = ICarbonableProject.owner(carbonable_project); + return (owner,); + } + + func balanceOf{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(owner: felt) -> (balance: Uint256) { + let (balance) = IERC721.balanceOf(carbonable_project, owner); + return (balance,); + } + + func ownerOf{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(tokenId: Uint256) -> (owner: felt) { + let (owner) = IERC721.ownerOf(carbonable_project, tokenId); + return (owner,); + } + + func totalSupply{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }() -> (totalSupply: Uint256) { + let (total_supply) = IERC721Enumerable.totalSupply(carbonable_project); + return (total_supply,); + } + + // Externals + + func set_minter{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(minter: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} + ICarbonableProject.set_minter(carbonable_project, minter); + %{ stop_prank() %} + return (); + } + + func approve{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(approved: felt, token_id: Uint256, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} + IERC721.approve(carbonable_project, approved, token_id); + %{ stop_prank() %} + return (); + } + + func mint{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt + }(to: felt, token_id: Uint256, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} + ICarbonableProject.mint(carbonable_project, to, token_id); + %{ stop_prank() %} + return (); + } +} + +namespace payment_token_instance { + // Internals + + func get_address() -> (payment_token_contract: felt) { + tempvar payment_token_contract; + %{ ids.payment_token_contract = context.payment_token_contract %} + return (payment_token_contract,); + } + + // Views + + func balanceOf{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt + }(account: felt) -> (balance: Uint256) { + let (balance) = IERC20.balanceOf(payment_token, account); + return (balance,); + } + + func allowance{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt + }(owner: felt, spender: felt) -> (remaining: Uint256) { + let (remaining) = IERC20.allowance(payment_token, owner, spender); + return (remaining,); + } + + // Externals + + func approve{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt + }(spender: felt, amount: Uint256, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(ids.caller, ids.payment_token) %} + let (success) = IERC20.approve(payment_token, spender, amount); + %{ stop_prank() %} + return (success,); + } + + func transfer{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, payment_token: felt + }(recipient: felt, amount: Uint256, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(ids.caller, ids.payment_token) %} + let (success) = IERC20.transfer(payment_token, recipient, amount); + %{ stop_prank() %} + return (success,); + } +} + +namespace carbonable_minter_instance { + // Internals + + func get_address() -> (carbonable_minter_contract: felt) { + tempvar carbonable_minter_contract; + %{ ids.carbonable_minter_contract = context.carbonable_minter_contract %} + return (carbonable_minter_contract,); + } + + // Views + + func carbonable_project_address{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (carbonable_project_address: felt) { + let (carbonable_project_address) = ICarbonableMinter.carbonable_project_address( + carbonable_minter + ); + return (carbonable_project_address,); + } + + func payment_token_address{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (payment_token_address: felt) { + let (payment_token_address) = ICarbonableMinter.payment_token_address(carbonable_minter); + return (payment_token_address,); + } + + func whitelisted_sale_open{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (whitelisted_sale_open: felt) { + let (whitelisted_sale_open) = ICarbonableMinter.whitelisted_sale_open(carbonable_minter); + return (whitelisted_sale_open,); + } + + func public_sale_open{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (public_sale_open: felt) { + let (public_sale_open) = ICarbonableMinter.public_sale_open(carbonable_minter); + return (public_sale_open,); + } + + func max_buy_per_tx{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (max_buy_per_tx: felt) { + let (max_buy_per_tx) = ICarbonableMinter.max_buy_per_tx(carbonable_minter); + return (max_buy_per_tx,); + } + + func unit_price{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (unit_price: Uint256) { + let (unit_price) = ICarbonableMinter.unit_price(carbonable_minter); + return (unit_price,); + } + + func max_supply_for_mint{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (max_supply_for_mint: Uint256) { + let (max_supply_for_mint) = ICarbonableMinter.max_supply_for_mint(carbonable_minter); + return (max_supply_for_mint,); + } + + func reserved_supply_for_mint{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (reserved_supply_for_mint: Uint256) { + let (reserved_supply_for_mint) = ICarbonableMinter.reserved_supply_for_mint( + carbonable_minter + ); + return (reserved_supply_for_mint,); + } + + func whitelist_merkle_root{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }() -> (whitelist_merkle_root: felt) { + let (whitelist_merkle_root) = ICarbonableMinter.whitelist_merkle_root(carbonable_minter); + return (whitelist_merkle_root,); + } + + func whitelisted_slots{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(account: felt, slots: felt, proof_len: felt, proof: felt*) -> (slots: felt) { + let (slots) = ICarbonableMinter.whitelisted_slots( + carbonable_minter, account, slots, proof_len, proof + ); + return (slots,); + } + + // Externals + + func decrease_reserved_supply_for_mint{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(slots: Uint256, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + ICarbonableMinter.decrease_reserved_supply_for_mint(carbonable_minter, slots); + %{ stop_prank() %} + return (); + } + + func withdraw{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + let (success) = ICarbonableMinter.withdraw(carbonable_minter); + %{ stop_prank() %} + return (success,); + } + + func set_whitelist_merkle_root{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(whitelist_merkle_root: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + ICarbonableMinter.set_whitelist_merkle_root(carbonable_minter, whitelist_merkle_root); + %{ stop_prank() %} + return (); + } + + func set_public_sale_open{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(public_sale_open: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + ICarbonableMinter.set_public_sale_open(carbonable_minter, public_sale_open); + %{ stop_prank() %} + return (); + } + + func set_max_buy_per_tx{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(max_buy_per_tx: felt, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + ICarbonableMinter.set_max_buy_per_tx(carbonable_minter, max_buy_per_tx); + %{ stop_prank() %} + return (); + } + + func set_unit_price{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(unit_price: Uint256, caller: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + ICarbonableMinter.set_unit_price(carbonable_minter, unit_price); + %{ stop_prank() %} + return (); + } + + func whitelist_buy{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(slots: felt, proof_len: felt, proof: felt*, quantity: felt, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + let (success) = ICarbonableMinter.whitelist_buy( + carbonable_minter, slots, proof_len, proof, quantity + ); + %{ stop_prank() %} + return (success,); + } + + func public_buy{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(quantity: felt, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + let (success) = ICarbonableMinter.public_buy(carbonable_minter, quantity); + %{ stop_prank() %} + return (success,); + } + + func airdrop{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_minter: felt + }(to: felt, quantity: felt, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_minter) %} + let (success) = ICarbonableMinter.airdrop(carbonable_minter, to, quantity); + %{ stop_prank() %} + return (success,); + } +} + +namespace carbonable_offseter_instance { + // Internals + + func get_address() -> (carbonable_offseter_contract: felt) { + tempvar carbonable_offseter_contract; + %{ ids.carbonable_offseter_contract = context.carbonable_offseter_contract %} + return (carbonable_offseter_contract=carbonable_offseter_contract,); + } + + // Views + + func carbonable_project_address{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }() -> (carbonable_project_address: felt) { + let (carbonable_project_address) = ICarbonableOffseter.carbonable_project_address( + carbonable_offseter + ); + return (carbonable_project_address=carbonable_project_address,); + } + + func is_locked{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }() -> (status: felt) { + let (status) = ICarbonableOffseter.is_locked(carbonable_offseter); + return (status=status,); + } + + func total_locked{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }() -> (balance: Uint256) { + let (balance) = ICarbonableOffseter.total_locked(carbonable_offseter); + return (balance=balance,); + } + + func balance_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(address: felt) -> (balance: felt) { + let (balance) = ICarbonableOffseter.balance_of(carbonable_offseter, address); + return (balance=balance,); + } + + func registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(token_id: Uint256) -> (address: felt) { + let (address) = ICarbonableOffseter.registred_owner_of(carbonable_offseter, token_id); + return (address=address,); + } + + // Externals + + func start_period{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(unlocked_duration: felt, period_duration: felt, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} + let (success) = ICarbonableOffseter.start_period( + carbonable_offseter, unlocked_duration, period_duration + ); + %{ stop_prank() %} + return (success=success,); + } + + func stop_period{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} + let (success) = ICarbonableOffseter.stop_period(carbonable_offseter); + %{ stop_prank() %} + return (success=success,); + } + + func deposit{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { + %{ stop_prank_offseter = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} + %{ stop_prank_project = start_prank(caller_address=ids.carbonable_offseter, target_contract_address=ids.carbonable_project) %} + let (success) = ICarbonableOffseter.deposit(carbonable_offseter, token_id); + %{ stop_prank_offseter() %} + %{ stop_prank_project() %} + return (success=success,); + } + + func withdraw{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_offseter: felt + }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { + %{ stop_prank_offseter = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_offseter) %} + %{ stop_prank_project = start_prank(caller_address=ids.carbonable_offseter, target_contract_address=ids.carbonable_project) %} + let (success) = ICarbonableOffseter.withdraw(carbonable_offseter, token_id); + %{ stop_prank_offseter() %} + %{ stop_prank_project() %} + return (success=success,); + } +} + +namespace carbonable_yielder_instance { + // Internals + + func get_address() -> (carbonable_yielder_contract: felt) { + tempvar carbonable_yielder_contract; + %{ ids.carbonable_yielder_contract = context.carbonable_yielder_contract %} + return (carbonable_yielder_contract=carbonable_yielder_contract,); + } + + // Views + + func carbonable_project_address{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }() -> (carbonable_project_address: felt) { + let (carbonable_project_address) = ICarbonableYielder.carbonable_project_address( + carbonable_yielder + ); + return (carbonable_project_address=carbonable_project_address,); + } + + func is_locked{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }() -> (status: felt) { + let (status) = ICarbonableYielder.is_locked(carbonable_yielder); + return (status=status,); + } + + func total_locked{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }() -> (balance: Uint256) { + let (balance) = ICarbonableYielder.total_locked(carbonable_yielder); + return (balance=balance,); + } + + func shares_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(address: felt, precision: felt) -> (shares: Uint256) { + let (shares) = ICarbonableYielder.shares_of(carbonable_yielder, address, precision); + return (shares=shares,); + } + + func registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(token_id: Uint256) -> (address: felt) { + let (address) = ICarbonableYielder.registred_owner_of(carbonable_yielder, token_id); + return (address=address,); + } + + // Externals + + func start_period{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(unlocked_duration: felt, period_duration: felt, caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} + let (success) = ICarbonableYielder.start_period( + carbonable_yielder, unlocked_duration, period_duration + ); + %{ stop_prank() %} + return (success=success,); + } + + func stop_period{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(caller: felt) -> (success: felt) { + %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} + let (success) = ICarbonableYielder.stop_period(carbonable_yielder); + %{ stop_prank() %} + return (success=success,); + } + + func deposit{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { + %{ stop_prank_yielder = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} + %{ stop_prank_project = start_prank(caller_address=ids.carbonable_yielder, target_contract_address=ids.carbonable_project) %} + let (success) = ICarbonableYielder.deposit(carbonable_yielder, token_id); + %{ stop_prank_yielder() %} + %{ stop_prank_project() %} + return (success=success,); + } + + func withdraw{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt + }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { + %{ stop_prank_yielder = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} + %{ stop_prank_project = start_prank(caller_address=ids.carbonable_yielder, target_contract_address=ids.carbonable_project) %} + let (success) = ICarbonableYielder.withdraw(carbonable_yielder, token_id); + %{ stop_prank_yielder() %} + %{ stop_prank_project() %} + return (success=success,); + } +} + +namespace admin_instance { + // Internals + + func get_address() -> (address: felt) { + tempvar address; + %{ ids.address = context.admin_account_contract %} + return (address,); + } + + // Project + + func owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) -> (owner: felt) { + let (carbonable_project) = carbonable_project_instance.get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + } + return (owner=owner,); + } + + func project_approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + approved: felt, token_id: felt + ) { + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + carbonable_project_instance.approve( + approved=approved, token_id=token_id_uint256, caller=caller + ); + } + return (); + } + + // Minter + + func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); + let (caller) = get_address(); + with payment_token { + let (initial_balance) = payment_token_instance.balanceOf(account=caller); + let (contract_balance) = payment_token_instance.balanceOf(account=carbonable_minter); + } + with carbonable_minter { + let (success) = carbonable_minter_instance.withdraw(caller=caller); + assert success = TRUE; + } + with payment_token { + let (returned_balance) = payment_token_instance.balanceOf(account=caller); + let (expected_balance) = SafeUint256.add(initial_balance, contract_balance); + assert returned_balance = expected_balance; + } + return (); + } + + func set_whitelist_merkle_root{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + whitelist_merkle_root: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + carbonable_minter_instance.set_whitelist_merkle_root( + whitelist_merkle_root=whitelist_merkle_root, caller=caller + ); + let (returned_whitelist_merkle_root) = carbonable_minter_instance.whitelist_merkle_root( + ); + assert returned_whitelist_merkle_root = whitelist_merkle_root; + } + return (); + } + + func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + public_sale_open: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + carbonable_minter_instance.set_public_sale_open( + public_sale_open=public_sale_open, caller=caller + ); + let (returned_public_sale_open) = carbonable_minter_instance.public_sale_open(); + assert returned_public_sale_open = public_sale_open; + } + return (); + } + + func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + max_buy_per_tx: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + carbonable_minter_instance.set_max_buy_per_tx( + max_buy_per_tx=max_buy_per_tx, caller=caller + ); + let (returned_max_buy_per_tx) = carbonable_minter_instance.max_buy_per_tx(); + assert returned_max_buy_per_tx = max_buy_per_tx; + } + return (); + } + + func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unit_price: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + let unit_price_uint256 = Uint256(unit_price, 0); + with carbonable_minter { + carbonable_minter_instance.set_unit_price(unit_price=unit_price_uint256, caller=caller); + let (returned_unit_price) = carbonable_minter_instance.unit_price(); + assert returned_unit_price = unit_price_uint256; + } + return (); + } + + func decrease_reserved_supply_for_mint{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr + }(slots: felt) { + alloc_locals; + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + let slots_uint256 = Uint256(slots, 0); + with carbonable_minter { + let (initial_supply) = carbonable_minter_instance.reserved_supply_for_mint(); + carbonable_minter_instance.decrease_reserved_supply_for_mint( + slots=slots_uint256, caller=caller + ); + let (returned_supply) = carbonable_minter_instance.reserved_supply_for_mint(); + let (expected_supply) = SafeUint256.sub_le(initial_supply, slots_uint256); + assert returned_supply = expected_supply; + } + return (); + } + + func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + with carbonable_project { + carbonable_project_instance.set_minter(minter=minter, caller=caller); + } + return (); + } + + func mint{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + to: felt, token_id: felt + ) { + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + carbonable_project_instance.mint(to=to, token_id=token_id_uint256, caller=caller); + } + return (); + } + + func airdrop{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + to: felt, quantity: felt + ) { + alloc_locals; + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let quantity_uint256 = Uint256(quantity, 0); + + // get user nft and payment token balances to check after buy + with carbonable_project { + let (initial_quantity) = carbonable_project_instance.balanceOf(owner=to); + let (intial_total_supply) = carbonable_project_instance.totalSupply(); + } + + // make the user to buy the quantity + with carbonable_minter { + let (initial_reserved_supply) = carbonable_minter_instance.reserved_supply_for_mint(); + let (success) = carbonable_minter_instance.airdrop( + to=to, quantity=quantity, caller=caller + ); + assert success = TRUE; + let (expected_reserved_supply) = SafeUint256.sub_le( + initial_reserved_supply, quantity_uint256 + ); + let (returned_reserved_supply) = carbonable_minter_instance.reserved_supply_for_mint(); + assert expected_reserved_supply = returned_reserved_supply; + } + + // check total supply and user nft quantity after buy + with carbonable_project { + let (returned_total_supply) = carbonable_project_instance.totalSupply(); + let (expected_total_supply) = SafeUint256.sub_le( + returned_total_supply, intial_total_supply + ); + assert expected_total_supply = quantity_uint256; + + let (returned_quantity) = carbonable_project_instance.balanceOf(owner=to); + let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); + assert expected_quantity = quantity_uint256; + } + + return (); + } + + // Offseter + + func offseter_is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + status: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (status) = carbonable_offseter_instance.is_locked(); + } + return (status=status,); + } + + func offseter_total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) -> (balance: Uint256) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (balance) = carbonable_offseter_instance.total_locked(); + } + return (balance=balance,); + } + + func offseter_balance_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + address: felt + ) -> (balance: felt) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (balance) = carbonable_offseter_instance.balance_of(address=address); + } + return (balance=balance,); + } + + func offseter_registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr + }(token_id: felt) -> (address: felt) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_offseter { + let (address) = carbonable_offseter_instance.registred_owner_of( + token_id=token_id_uint256 + ); + } + return (address=address,); + } + + func offseter_start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unlocked_duration: felt, period_duration: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (caller) = get_address(); + with carbonable_offseter { + let (success) = carbonable_offseter_instance.start_period( + unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller + ); + assert success = TRUE; + } + return (); + } + + func offseter_stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (caller) = get_address(); + with carbonable_offseter { + let (success) = carbonable_offseter_instance.stop_period(caller=caller); + assert success = TRUE; + } + return (); + } + + func offseter_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + with carbonable_offseter { + let (success) = carbonable_offseter_instance.deposit( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_offseter; + } + return (); + } + + func offseter_withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_offseter; + } + with carbonable_offseter { + let (success) = carbonable_offseter_instance.withdraw( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + return (); + } + + // Yielder + + func yielder_is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + status: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (status) = carbonable_yielder_instance.is_locked(); + } + return (status=status,); + } + + func yielder_total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) -> (balance: Uint256) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (balance) = carbonable_yielder_instance.total_locked(); + } + return (balance=balance,); + } + + func yielder_shares_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + address: felt, precision: felt + ) -> (shares: Uint256) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (shares) = carbonable_yielder_instance.shares_of( + address=address, precision=precision + ); + } + return (shares=shares,); + } + + func yielder_registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr + }(token_id: felt) -> (address: felt) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_yielder { + let (address) = carbonable_yielder_instance.registred_owner_of( + token_id=token_id_uint256 + ); + } + return (address=address,); + } + + func yielder_start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unlocked_duration: felt, period_duration: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (caller) = get_address(); + with carbonable_yielder { + let (success) = carbonable_yielder_instance.start_period( + unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller + ); + assert success = TRUE; + } + return (); + } + + func yielder_stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (caller) = get_address(); + with carbonable_yielder { + let (success) = carbonable_yielder_instance.stop_period(caller=caller); + assert success = TRUE; + } + return (); + } + + func yielder_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + with carbonable_yielder { + let (success) = carbonable_yielder_instance.deposit( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_yielder; + } + return (); + } + + func yielder_withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_yielder; + } + with carbonable_yielder { + let (success) = carbonable_yielder_instance.withdraw( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + return (); + } +} + +namespace anyone_instance { + // Internals + + func get_address() -> (address: felt) { + tempvar address; + %{ ids.address = context.anyone_account_contract %} + return (address,); + } + + func get_slots() -> (slots: felt) { + tempvar slots; + %{ ids.slots = context.whitelist.slots %} + return (slots,); + } + + func get_proof_len() -> (proof_len: felt) { + tempvar proof_len; + %{ ids.proof_len = context.whitelist.merkle_proof_len %} + return (proof_len,); + } + + func get_proof() -> (proof: felt*) { + alloc_locals; + let (local proof: felt*) = alloc(); + %{ + for index, node in enumerate(context.whitelist.merkle_proof): + memory[ids.proof + index] = node + %} + return (proof,); + } + + // Project + + func project_approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + approved: felt, token_id: felt + ) { + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + carbonable_project_instance.approve( + approved=approved, token_id=token_id_uint256, caller=caller + ); + } + return (); + } + + // Token + + func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(quantity: felt) { + alloc_locals; + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + let (unit_price) = carbonable_minter_instance.unit_price(); + let (allowance) = SafeUint256.mul(Uint256(quantity, 0), unit_price); + } + with payment_token { + let (success) = payment_token_instance.approve( + spender=carbonable_minter, amount=allowance, caller=caller + ); + assert success = TRUE; + let (returned_allowance) = payment_token_instance.allowance( + owner=caller, spender=carbonable_minter + ); + assert returned_allowance = allowance; + } + return (); + } + + func transfer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + recipient: felt, amount: felt + ) { + let (payment_token) = payment_token_instance.get_address(); + let (caller) = get_address(); + let amount_uint256 = Uint256(low=amount, high=0); + with payment_token { + let (success) = payment_token_instance.transfer( + recipient=recipient, amount=amount_uint256, caller=caller + ); + assert success = TRUE; + } + return (); + } + + // Minter + + func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + public_sale_open: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + carbonable_minter_instance.set_public_sale_open( + public_sale_open=public_sale_open, caller=caller + ); + let (returned_public_sale_open) = carbonable_minter_instance.public_sale_open(); + assert returned_public_sale_open = public_sale_open; + } + return (); + } + + func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + max_buy_per_tx: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + with carbonable_minter { + carbonable_minter_instance.set_max_buy_per_tx( + max_buy_per_tx=max_buy_per_tx, caller=caller + ); + let (returned_max_buy_per_tx) = carbonable_minter_instance.max_buy_per_tx(); + assert returned_max_buy_per_tx = max_buy_per_tx; + } + return (); + } + + func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unit_price: felt + ) { + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (caller) = get_address(); + let unit_price_uint256 = Uint256(unit_price, 0); + with carbonable_minter { + carbonable_minter_instance.set_unit_price(unit_price=unit_price_uint256, caller=caller); + let (returned_unit_price) = carbonable_minter_instance.unit_price(); + assert returned_unit_price = unit_price_uint256; + } + return (); + } + + func whitelist_buy{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + quantity: felt + ) { + alloc_locals; + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); + let (caller) = get_address(); + let (slots) = get_slots(); + let (proof_len) = get_proof_len(); + let (proof) = get_proof(); + + // get user nft and payment token balances to check after buy + with carbonable_project { + let (initial_quantity) = carbonable_project_instance.balanceOf(owner=caller); + let (intial_total_supply) = carbonable_project_instance.totalSupply(); + } + with payment_token { + let (initial_balance) = payment_token_instance.balanceOf(account=caller); + } + + // make the user to buy the quantity + with carbonable_minter { + let (whitelist_merkle_root) = carbonable_minter_instance.whitelist_merkle_root(); + let (unit_price) = carbonable_minter_instance.unit_price(); + let (success) = carbonable_minter_instance.whitelist_buy( + slots=slots, proof_len=proof_len, proof=proof, quantity=quantity, caller=caller + ); + assert success = TRUE; + } + + // check total supply and user nft quantity after buy + with carbonable_project { + let (returned_total_supply) = carbonable_project_instance.totalSupply(); + let (expected_total_supply) = SafeUint256.sub_le( + returned_total_supply, intial_total_supply + ); + assert expected_total_supply = Uint256(quantity, 0); + + let (returned_quantity) = carbonable_project_instance.balanceOf(owner=caller); + let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); + assert expected_quantity = Uint256(quantity, 0); + } + + // check user payment token balance after buy + with payment_token { + let (returned_balance) = payment_token_instance.balanceOf(account=caller); + let (expected_spend) = SafeUint256.sub_le(initial_balance, returned_balance); + let (spend) = SafeUint256.mul(Uint256(quantity, 0), unit_price); + assert expected_spend = spend; + } + return (); + } + + func public_buy{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + quantity: felt + ) { + alloc_locals; + let (carbonable_minter) = carbonable_minter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (payment_token) = payment_token_instance.get_address(); + let (caller) = get_address(); + + // get user nft and payment token balances to check after buy + with carbonable_project { + let (initial_quantity) = carbonable_project_instance.balanceOf(owner=caller); + let (intial_total_supply) = carbonable_project_instance.totalSupply(); + } + with payment_token { + let (initial_balance) = payment_token_instance.balanceOf(account=caller); + } + + // make the user to buy the quantity + with carbonable_minter { + let (unit_price) = carbonable_minter_instance.unit_price(); + let (success) = carbonable_minter_instance.public_buy(quantity=quantity, caller=caller); + assert success = TRUE; + } + + // check total supply and user nft quantity after buy + with carbonable_project { + let (returned_total_supply) = carbonable_project_instance.totalSupply(); + let (expected_total_supply) = SafeUint256.sub_le( + returned_total_supply, intial_total_supply + ); + assert expected_total_supply = Uint256(quantity, 0); + + let (returned_quantity) = carbonable_project_instance.balanceOf(owner=caller); + let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); + assert expected_quantity = Uint256(quantity, 0); + } + + // check user payment token balance after buy + with payment_token { + let (returned_balance) = payment_token_instance.balanceOf(account=caller); + let (expected_spend) = SafeUint256.sub_le(initial_balance, returned_balance); + let (spend) = SafeUint256.mul(Uint256(quantity, 0), unit_price); + assert expected_spend = spend; + } + return (); + } + + // Offseter + + func offseter_is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + status: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (status) = carbonable_offseter_instance.is_locked(); + } + return (status=status,); + } + + func offseter_total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) -> (balance: Uint256) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (balance) = carbonable_offseter_instance.total_locked(); + } + return (balance=balance,); + } + + func offseter_balance_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + address: felt + ) -> (balance: felt) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + with carbonable_offseter { + let (balance) = carbonable_offseter_instance.balance_of(address=address); + } + return (balance=balance,); + } + + func offseter_registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr + }(token_id: felt) -> (address: felt) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_offseter { + let (address) = carbonable_offseter_instance.registred_owner_of( + token_id=token_id_uint256 + ); + } + return (address=address,); + } + + func offseter_start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unlocked_duration: felt, period_duration: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (caller) = get_address(); + with carbonable_offseter { + let (success) = carbonable_offseter_instance.start_period( + unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller + ); + assert success = TRUE; + } + return (); + } + + func offseter_stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (caller) = get_address(); + with carbonable_offseter { + let (success) = carbonable_offseter_instance.stop_period(caller=caller); + assert success = TRUE; + } + return (); + } + + func offseter_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + with carbonable_offseter { + let (success) = carbonable_offseter_instance.deposit( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_offseter; + } + return (); + } + + func offseter_withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_offseter) = carbonable_offseter_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_offseter; + } + with carbonable_offseter { + let (success) = carbonable_offseter_instance.withdraw( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + return (); + } + + // Yielder + + func yielder_is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( + status: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (status) = carbonable_yielder_instance.is_locked(); + } + return (status=status,); + } + + func yielder_total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) -> (balance: Uint256) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (balance) = carbonable_yielder_instance.total_locked(); + } + return (balance=balance,); + } + + func yielder_shares_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + address: felt, precision: felt + ) -> (shares: Uint256) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + with carbonable_yielder { + let (shares) = carbonable_yielder_instance.shares_of( + address=address, precision=precision + ); + } + return (shares=shares,); + } + + func yielder_registred_owner_of{ + syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr + }(token_id: felt) -> (address: felt) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_yielder { + let (address) = carbonable_yielder_instance.registred_owner_of( + token_id=token_id_uint256 + ); + } + return (address=address,); + } + + func yielder_start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + unlocked_duration: felt, period_duration: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (caller) = get_address(); + with carbonable_yielder { + let (success) = carbonable_yielder_instance.start_period( + unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller + ); + assert success = TRUE; + } + return (); + } + + func yielder_stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (caller) = get_address(); + with carbonable_yielder { + let (success) = carbonable_yielder_instance.stop_period(caller=caller); + assert success = TRUE; + } + return (); + } + + func yielder_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + with carbonable_yielder { + let (success) = carbonable_yielder_instance.deposit( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_yielder; + } + return (); + } + + func yielder_withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + token_id: felt + ) { + let (carbonable_yielder) = carbonable_yielder_instance.get_address(); + let (carbonable_project) = carbonable_project_instance.get_address(); + let (caller) = get_address(); + let token_id_uint256 = Uint256(low=token_id, high=0); + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = carbonable_yielder; + } + with carbonable_yielder { + let (success) = carbonable_yielder_instance.withdraw( + token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project + ); + assert success = TRUE; + } + with carbonable_project { + let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); + assert owner = caller; + } + return (); + } +} diff --git a/tests/integrations/offseter/test_nominal_cases.cairo b/tests/integrations/protocol/test_offseter.cairo similarity index 62% rename from tests/integrations/offseter/test_nominal_cases.cairo rename to tests/integrations/protocol/test_offseter.cairo index bbf3c352..f652fc9f 100644 --- a/tests/integrations/offseter/test_nominal_cases.cairo +++ b/tests/integrations/protocol/test_offseter.cairo @@ -8,7 +8,7 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin from starkware.cairo.common.uint256 import Uint256 // Local dependencies -from tests.integrations.offseter.library import ( +from tests.integrations.protocol.library import ( setup, admin_instance as admin, anyone_instance as anyone, @@ -33,7 +33,7 @@ func __setup__{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( } @view -func test_e2e_deposit_and_withdraw_while_unlock{ +func test_deposit_and_withdraw_while_unlock{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin start a 10s period with 5s unlock @@ -61,71 +61,77 @@ func test_e2e_deposit_and_withdraw_while_unlock{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (offseter_address) = offseter.deployed(); + let (offseter_address) = offseter.get_address(); - admin.start_period(unlocked_duration=5, period_duration=10); + // Mint tokens + admin.mint(to=admin_address, token_id=1); + admin.mint(to=admin_address, token_id=2); + admin.mint(to=anyone_address, token_id=3); + admin.mint(to=anyone_address, token_id=4); + admin.mint(to=anyone_address, token_id=5); + + admin.offseter_start_period(unlocked_duration=5, period_duration=10); %{ stop_warp = warp(blk_timestamp=5, target_contract_address=ids.offseter_address) %} - anyone.approve(approved=offseter_address, token_id=3); - anyone.deposit(token_id=3); - anyone.withdraw(token_id=3); - anyone.approve(approved=offseter_address, token_id=3); - anyone.deposit(token_id=3); - anyone.approve(approved=offseter_address, token_id=4); - anyone.deposit(token_id=4); - - let (balance) = anyone.balance_of(anyone_address); + anyone.project_approve(approved=offseter_address, token_id=3); + anyone.offseter_deposit(token_id=3); + anyone.offseter_withdraw(token_id=3); + anyone.project_approve(approved=offseter_address, token_id=3); + anyone.offseter_deposit(token_id=3); + anyone.project_approve(approved=offseter_address, token_id=4); + anyone.offseter_deposit(token_id=4); + + let (balance) = anyone.offseter_balance_of(anyone_address); assert balance = 2; - admin.approve(approved=offseter_address, token_id=1); - admin.deposit(token_id=1); + admin.project_approve(approved=offseter_address, token_id=1); + admin.offseter_deposit(token_id=1); %{ stop_warp() %} - let (owner) = anyone.registred_owner_of(token_id=3); + let (owner) = anyone.offseter_registred_owner_of(token_id=3); assert owner = anyone_address; - let (owner) = anyone.registred_owner_of(token_id=1); + let (owner) = anyone.offseter_registred_owner_of(token_id=1); assert owner = admin_address; - let (balance) = anyone.balance_of(anyone_address); + let (balance) = anyone.offseter_balance_of(anyone_address); assert balance = 2; - let (balance) = anyone.balance_of(admin_address); + let (balance) = anyone.offseter_balance_of(admin_address); assert balance = 1; - let (total_balance) = anyone.total_locked(); + let (total_balance) = anyone.offseter_total_locked(); assert total_balance = Uint256(low=3, high=0); %{ stop_warp = warp(blk_timestamp=10, target_contract_address=ids.offseter_address) %} - anyone.withdraw(token_id=3); + anyone.offseter_withdraw(token_id=3); - let (balance) = anyone.balance_of(anyone_address); + let (balance) = anyone.offseter_balance_of(anyone_address); assert balance = 1; - admin.withdraw(token_id=1); + admin.offseter_withdraw(token_id=1); - let (balance) = anyone.balance_of(admin_address); + let (balance) = anyone.offseter_balance_of(admin_address); assert balance = 0; - let (balance) = anyone.balance_of(anyone_address); + let (balance) = anyone.offseter_balance_of(anyone_address); assert balance = 1; - anyone.withdraw(token_id=4); + anyone.offseter_withdraw(token_id=4); %{ stop_warp() %} - let (balance) = anyone.balance_of(anyone_address); + let (balance) = anyone.offseter_balance_of(anyone_address); assert balance = 0; %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: token_id has not been registred") %} - let (owner) = anyone.registred_owner_of(token_id=1); + let (owner) = anyone.offseter_registred_owner_of(token_id=1); return (); } @view -func test_e2e_deposit_revert_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr -}() { +func test_deposit_revert_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) { // When admin start a 10s period with 5s unlock // And anyone approves offseter for token 3 at time 1 // And anyone deposits token 3 to offseter at time 6 @@ -133,24 +139,26 @@ func test_e2e_deposit_revert_locked{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (offseter_address) = offseter.deployed(); + let (offseter_address) = offseter.get_address(); + + // Mint tokens + admin.mint(to=anyone_address, token_id=3); - admin.start_period(unlocked_duration=5, period_duration=10); + admin.offseter_start_period(unlocked_duration=5, period_duration=10); - anyone.approve(approved=offseter_address, token_id=3); + anyone.project_approve(approved=offseter_address, token_id=3); %{ stop_warp = warp(blk_timestamp=6, target_contract_address=ids.offseter_address) %} %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: deposits are currently locked") %} - anyone.deposit(token_id=3); + anyone.offseter_deposit(token_id=3); %{ stop_warp() %} return (); } @view -func test_e2e_withdraw_revert_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr -}() { +func test_withdraw_revert_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) { // When admin start a 10s period with 5s unlock // And anyone approves offseter for token 3 at time 1 // And anyone deposits token 3 to offseter at time 5 @@ -159,25 +167,28 @@ func test_e2e_withdraw_revert_locked{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (offseter_address) = offseter.deployed(); + let (offseter_address) = offseter.get_address(); + + // Mint tokens + admin.mint(to=anyone_address, token_id=3); - admin.start_period(unlocked_duration=5, period_duration=10); - anyone.approve(approved=offseter_address, token_id=3); + admin.offseter_start_period(unlocked_duration=5, period_duration=10); + anyone.project_approve(approved=offseter_address, token_id=3); %{ stop_warp = warp(blk_timestamp=5, target_contract_address=ids.offseter_address) %} - anyone.deposit(token_id=3); + anyone.offseter_deposit(token_id=3); %{ stop_warp() %} %{ stop_warp = warp(blk_timestamp=6, target_contract_address=ids.offseter_address) %} %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: withdrawals are currently locked") %} - anyone.withdraw(token_id=3); + anyone.offseter_withdraw(token_id=3); %{ stop_warp() %} return (); } @view -func test_e2e_start_and_start_and_stop_period{ +func test_start_and_start_and_stop_period{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin start a 10s period with 5s unlock @@ -187,17 +198,17 @@ func test_e2e_start_and_start_and_stop_period{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (offseter_address) = offseter.deployed(); + let (offseter_address) = offseter.get_address(); - admin.start_period(unlocked_duration=5, period_duration=10); - admin.start_period(unlocked_duration=10, period_duration=20); - admin.stop_period(); + admin.offseter_start_period(unlocked_duration=5, period_duration=10); + admin.offseter_start_period(unlocked_duration=10, period_duration=20); + admin.offseter_stop_period(); return (); } @view -func test_e2e_start_period_revert_not_owner{ +func test_start_period_revert_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone starts a 10s period with 5s unlock @@ -205,13 +216,13 @@ func test_e2e_start_period_revert_not_owner{ alloc_locals; %{ expect_revert("TRANSACTION_FAILED", "Ownable: caller is not the owner") %} - anyone.start_period(unlocked_duration=5, period_duration=10); + anyone.offseter_start_period(unlocked_duration=5, period_duration=10); return (); } @view -func test_e2e_stop_period_revert_not_owner{ +func test_stop_period_revert_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin starts a 10s period with 5s unlock @@ -219,9 +230,9 @@ func test_e2e_stop_period_revert_not_owner{ // Then a failed transaction is expected alloc_locals; - admin.start_period(unlocked_duration=5, period_duration=10); + admin.offseter_start_period(unlocked_duration=5, period_duration=10); %{ expect_revert("TRANSACTION_FAILED", "Ownable: caller is not the owner") %} - anyone.stop_period(); + anyone.offseter_stop_period(); return (); } diff --git a/tests/integrations/yielder/test_nominal_cases.cairo b/tests/integrations/protocol/test_yielder.cairo similarity index 61% rename from tests/integrations/yielder/test_nominal_cases.cairo rename to tests/integrations/protocol/test_yielder.cairo index 656d0ef5..63233b04 100644 --- a/tests/integrations/yielder/test_nominal_cases.cairo +++ b/tests/integrations/protocol/test_yielder.cairo @@ -8,7 +8,7 @@ from starkware.cairo.common.cairo_builtins import HashBuiltin from starkware.cairo.common.uint256 import Uint256 // Local dependencies -from tests.integrations.yielder.library import ( +from tests.integrations.protocol.library import ( setup, admin_instance as admin, anyone_instance as anyone, @@ -17,23 +17,23 @@ from tests.integrations.yielder.library import ( @view func __setup__{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - // Given a deployed user contracts + // Given a get_address user contracts // And an admin with address 1000 // And an anyone with address 1001 - // Given a deployed project contact + // Given a get_address project contact // And owned by admin // And with token 1 owned by admin // And with token 2 owned by admin // And with token 3 owned by anyone // And with token 4 owned by anyone // And with token 5 owned by anyone - // Given a deployed farmer contract + // Given a get_address farmer contract // And owned by admin return setup(); } @view -func test_e2e_deposit_and_withdraw_while_unlock{ +func test_deposit_and_withdraw_while_unlock{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin starts a 10s period with 5s unlock @@ -59,65 +59,70 @@ func test_e2e_deposit_and_withdraw_while_unlock{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (yielder_address) = yielder.deployed(); + let (yielder_address) = yielder.get_address(); - admin.start_period(unlocked_duration=5, period_duration=10); + // Mint tokens + admin.mint(to=admin_address, token_id=1); + admin.mint(to=admin_address, token_id=2); + admin.mint(to=anyone_address, token_id=3); + admin.mint(to=anyone_address, token_id=4); + admin.mint(to=anyone_address, token_id=5); + + admin.yielder_start_period(unlocked_duration=5, period_duration=10); %{ stop_warp = warp(blk_timestamp=5, target_contract_address=ids.yielder_address) %} - anyone.approve(approved=yielder_address, token_id=3); - anyone.deposit(token_id=3); - anyone.withdraw(token_id=3); - anyone.approve(approved=yielder_address, token_id=3); - anyone.deposit(token_id=3); - anyone.approve(approved=yielder_address, token_id=4); - anyone.deposit(token_id=4); - - let (shares) = anyone.shares_of(anyone_address, precision=100); + anyone.project_approve(approved=yielder_address, token_id=3); + anyone.yielder_deposit(token_id=3); + anyone.yielder_withdraw(token_id=3); + anyone.project_approve(approved=yielder_address, token_id=3); + anyone.yielder_deposit(token_id=3); + anyone.project_approve(approved=yielder_address, token_id=4); + anyone.yielder_deposit(token_id=4); + + let (shares) = anyone.yielder_shares_of(anyone_address, precision=100); assert shares = Uint256(low=100, high=0); - admin.approve(approved=yielder_address, token_id=1); - admin.deposit(token_id=1); + admin.project_approve(approved=yielder_address, token_id=1); + admin.yielder_deposit(token_id=1); %{ stop_warp() %} - let (owner) = anyone.registred_owner_of(token_id=3); + let (owner) = anyone.yielder_registred_owner_of(token_id=3); assert owner = anyone_address; - let (owner) = anyone.registred_owner_of(token_id=1); + let (owner) = anyone.yielder_registred_owner_of(token_id=1); assert owner = admin_address; - let (shares) = anyone.shares_of(anyone_address, precision=100); + let (shares) = anyone.yielder_shares_of(anyone_address, precision=100); assert shares = Uint256(low=66, high=0); - let (balance) = anyone.total_locked(); + let (balance) = anyone.yielder_total_locked(); assert balance = Uint256(low=3, high=0); %{ stop_warp = warp(blk_timestamp=10, target_contract_address=ids.yielder_address) %} - anyone.withdraw(token_id=3); + anyone.yielder_withdraw(token_id=3); - let (shares) = anyone.shares_of(anyone_address, precision=100); + let (shares) = anyone.yielder_shares_of(anyone_address, precision=100); assert shares = Uint256(low=50, high=0); - admin.withdraw(token_id=1); + admin.yielder_withdraw(token_id=1); - let (shares) = anyone.shares_of(anyone_address, precision=100); + let (shares) = anyone.yielder_shares_of(anyone_address, precision=100); assert shares = Uint256(low=100, high=0); - anyone.withdraw(token_id=4); + anyone.yielder_withdraw(token_id=4); %{ stop_warp() %} - let (shares) = anyone.shares_of(anyone_address, precision=100); + let (shares) = anyone.yielder_shares_of(anyone_address, precision=100); assert shares = Uint256(low=0, high=0); %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: token_id has not been registred") %} - let (owner) = anyone.registred_owner_of(token_id=1); + let (owner) = anyone.yielder_registred_owner_of(token_id=1); return (); } @view -func test_e2e_deposit_revert_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr -}() { +func test_deposit_revert_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { // When admin starts a 10s period with 5s unlock // And anyone approves yielder for token 3 at time 1 // And anyone deposits token 3 to yielder at time 6 @@ -125,24 +130,26 @@ func test_e2e_deposit_revert_locked{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (yielder_address) = yielder.deployed(); + let (yielder_address) = yielder.get_address(); + + // Mint tokens + admin.mint(to=anyone_address, token_id=3); - admin.start_period(unlocked_duration=5, period_duration=10); + admin.yielder_start_period(unlocked_duration=5, period_duration=10); - anyone.approve(approved=yielder_address, token_id=3); + anyone.project_approve(approved=yielder_address, token_id=3); %{ stop_warp = warp(blk_timestamp=6, target_contract_address=ids.yielder_address) %} %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: deposits are currently locked") %} - anyone.deposit(token_id=3); + anyone.yielder_deposit(token_id=3); %{ stop_warp() %} return (); } @view -func test_e2e_withdraw_revert_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr -}() { +func test_withdraw_revert_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( + ) { // When admin starts a 10s period with 5s unlock // And anyone approves yielder for token 3 at time 1 // And anyone deposits token 3 to yielder at time 5 @@ -151,25 +158,28 @@ func test_e2e_withdraw_revert_locked{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (yielder_address) = yielder.deployed(); + let (yielder_address) = yielder.get_address(); + + // Mint tokens + admin.mint(to=anyone_address, token_id=3); - admin.start_period(unlocked_duration=5, period_duration=10); - anyone.approve(approved=yielder_address, token_id=3); + admin.yielder_start_period(unlocked_duration=5, period_duration=10); + anyone.project_approve(approved=yielder_address, token_id=3); %{ stop_warp = warp(blk_timestamp=5, target_contract_address=ids.yielder_address) %} - anyone.deposit(token_id=3); + anyone.yielder_deposit(token_id=3); %{ stop_warp() %} %{ stop_warp = warp(blk_timestamp=6, target_contract_address=ids.yielder_address) %} %{ expect_revert("TRANSACTION_FAILED", "CarbonableFarmer: withdrawals are currently locked") %} - anyone.withdraw(token_id=3); + anyone.yielder_withdraw(token_id=3); %{ stop_warp() %} return (); } @view -func test_e2e_start_and_start_and_stop_period{ +func test_start_and_start_and_stop_period{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin starts a 10s period with 5s unlock @@ -179,17 +189,17 @@ func test_e2e_start_and_start_and_stop_period{ alloc_locals; let (admin_address) = admin.get_address(); let (anyone_address) = anyone.get_address(); - let (yielder_address) = yielder.deployed(); + let (yielder_address) = yielder.get_address(); - admin.start_period(unlocked_duration=5, period_duration=10); - admin.start_period(unlocked_duration=10, period_duration=20); - admin.stop_period(); + admin.yielder_start_period(unlocked_duration=5, period_duration=10); + admin.yielder_start_period(unlocked_duration=10, period_duration=20); + admin.yielder_stop_period(); return (); } @view -func test_e2e_start_period_revert_not_owner{ +func test_start_period_revert_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When anyone starts a 10s period with 5s unlock @@ -197,13 +207,13 @@ func test_e2e_start_period_revert_not_owner{ alloc_locals; %{ expect_revert("TRANSACTION_FAILED", "Ownable: caller is not the owner") %} - anyone.start_period(unlocked_duration=5, period_duration=10); + anyone.yielder_start_period(unlocked_duration=5, period_duration=10); return (); } @view -func test_e2e_stop_period_revert_not_owner{ +func test_stop_period_revert_not_owner{ syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr }() { // When admin starts a 10s period with 5s unlock @@ -211,9 +221,9 @@ func test_e2e_stop_period_revert_not_owner{ // Then a failed transaction is expected alloc_locals; - admin.start_period(unlocked_duration=5, period_duration=10); + admin.yielder_start_period(unlocked_duration=5, period_duration=10); %{ expect_revert("TRANSACTION_FAILED", "Ownable: caller is not the owner") %} - anyone.stop_period(); + anyone.yielder_stop_period(); return (); } diff --git a/tests/integrations/yielder/library.cairo b/tests/integrations/yielder/library.cairo deleted file mode 100644 index 48cba6f4..00000000 --- a/tests/integrations/yielder/library.cairo +++ /dev/null @@ -1,606 +0,0 @@ -// SPDX-License-Identifier: MIT - -%lang starknet - -// Starkware dependencies -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.bool import TRUE, FALSE -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.cairo.common.uint256 import Uint256 - -// Project dependencies -from openzeppelin.token.erc20.IERC20 import IERC20 -from openzeppelin.token.erc721.IERC721 import IERC721 -from openzeppelin.token.erc721.enumerable.IERC721Enumerable import IERC721Enumerable -from openzeppelin.security.safemath.library import SafeUint256 - -// Local dependencies -from interfaces.yielder import ICarbonableYielder -from interfaces.project import ICarbonableProject - -// -// Functions -// - -func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - alloc_locals; - %{ - # Load config - import sys - sys.path.append('.') - from tests import load - load("./tests/integrations/yielder/config.yml", context) - - # Admin account deployment - context.admin_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.admin, - }, - ).contract_address - - # Anyone account deployment - context.anyone_account_contract = deploy_contract( - contract=context.sources.account, - constructor_args={ - "public_key": context.signers.anyone, - }, - ).contract_address - - # Carbonable project deployment - context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash - calldata = { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.admin_account_contract, - "proxy_admin": context.admin_account_contract, - } - context.carbonable_project_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_project_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - - # Carbonable yielder deployment - context.carbonable_yielder_class_hash = declare(contract=context.sources.yielder).class_hash - calldata = { - "carbonable_project_address": context.carbonable_project_contract, - "owner": context.admin_account_contract, - "proxy_admin": context.admin_account_contract, - } - context.carbonable_yielder_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_yielder_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - %} - - // Mint 2 tokens to admin and 3 tokens to anyone - let (local admin_address) = admin_instance.get_address(); - let (local anyone_address) = anyone_instance.get_address(); - - admin_instance.set_minter(admin_address); - - admin_instance.mint(to=admin_address, token_id=1); - admin_instance.mint(to=admin_address, token_id=2); - admin_instance.mint(to=anyone_address, token_id=3); - admin_instance.mint(to=anyone_address, token_id=4); - admin_instance.mint(to=anyone_address, token_id=5); - return (); -} - -namespace carbonable_project_instance { - // Internals - - func deployed() -> (carbonable_project_contract: felt) { - tempvar carbonable_project_contract; - %{ ids.carbonable_project_contract = context.carbonable_project_contract %} - return (carbonable_project_contract,); - } - - // Views - - func owner{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (owner: felt) { - let (owner: felt) = ICarbonableProject.owner(carbonable_project); - return (owner,); - } - - func balanceOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(owner: felt) -> (balance: Uint256) { - let (balance) = IERC721.balanceOf(carbonable_project, owner); - return (balance,); - } - - func ownerOf{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(tokenId: Uint256) -> (owner: felt) { - let (owner) = IERC721.ownerOf(carbonable_project, tokenId); - return (owner,); - } - - func totalSupply{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }() -> (totalSupply: Uint256) { - let (total_supply) = IERC721Enumerable.totalSupply(carbonable_project); - return (total_supply,); - } - - // Externals - - func set_minter{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(minter: felt, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.set_minter(carbonable_project, minter); - %{ stop_prank() %} - return (); - } - - func approve{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(approved: felt, token_id: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - IERC721.approve(carbonable_project, approved, token_id); - %{ stop_prank() %} - return (); - } - - func mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_project: felt - }(to: felt, token_id: Uint256, caller: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_project) %} - ICarbonableProject.mint(carbonable_project, to, token_id); - %{ stop_prank() %} - return (); - } -} - -namespace carbonable_yielder_instance { - // Internals - - func deployed() -> (carbonable_yielder_contract: felt) { - tempvar carbonable_yielder_contract; - %{ ids.carbonable_yielder_contract = context.carbonable_yielder_contract %} - return (carbonable_yielder_contract=carbonable_yielder_contract,); - } - - // Views - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }() -> (carbonable_project_address: felt) { - let (carbonable_project_address) = ICarbonableYielder.carbonable_project_address( - carbonable_yielder - ); - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }() -> (status: felt) { - let (status) = ICarbonableYielder.is_locked(carbonable_yielder); - return (status=status,); - } - - func total_locked{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }() -> (balance: Uint256) { - let (balance) = ICarbonableYielder.total_locked(carbonable_yielder); - return (balance=balance,); - } - - func shares_of{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(address: felt, precision: felt) -> (shares: Uint256) { - let (shares) = ICarbonableYielder.shares_of(carbonable_yielder, address, precision); - return (shares=shares,); - } - - func registred_owner_of{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(token_id: Uint256) -> (address: felt) { - let (address) = ICarbonableYielder.registred_owner_of(carbonable_yielder, token_id); - return (address=address,); - } - - // Externals - - func start_period{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(unlocked_duration: felt, period_duration: felt, caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} - let (success) = ICarbonableYielder.start_period( - carbonable_yielder, unlocked_duration, period_duration - ); - %{ stop_prank() %} - return (success=success,); - } - - func stop_period{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(caller: felt) -> (success: felt) { - %{ stop_prank = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} - let (success) = ICarbonableYielder.stop_period(carbonable_yielder); - %{ stop_prank() %} - return (success=success,); - } - - func deposit{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { - %{ stop_prank_yielder = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} - %{ stop_prank_project = start_prank(caller_address=ids.carbonable_yielder, target_contract_address=ids.carbonable_project) %} - let (success) = ICarbonableYielder.deposit(carbonable_yielder, token_id); - %{ stop_prank_yielder() %} - %{ stop_prank_project() %} - return (success=success,); - } - - func withdraw{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, carbonable_yielder: felt - }(token_id: Uint256, caller: felt, carbonable_project: felt) -> (success: felt) { - %{ stop_prank_yielder = start_prank(caller_address=ids.caller, target_contract_address=ids.carbonable_yielder) %} - %{ stop_prank_project = start_prank(caller_address=ids.carbonable_yielder, target_contract_address=ids.carbonable_project) %} - let (success) = ICarbonableYielder.withdraw(carbonable_yielder, token_id); - %{ stop_prank_yielder() %} - %{ stop_prank_project() %} - return (success=success,); - } -} - -namespace admin_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar admin; - %{ ids.admin = context.admin_account_contract %} - return (admin,); - } - - // Views - - func owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (owner: felt) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - } - return (owner=owner,); - } - - func balance_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - owner: felt - ) -> (balance: Uint256) { - let (carbonable_project) = carbonable_project_instance.deployed(); - with carbonable_project { - let (balance) = carbonable_project_instance.balanceOf(owner=owner); - } - return (balance=balance,); - } - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr - }() -> (carbonable_project_address: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let ( - carbonable_project_address - ) = carbonable_yielder_instance.carbonable_project_address(); - } - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - status: felt - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (status) = carbonable_yielder_instance.is_locked(); - } - return (status=status,); - } - - func total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - balance: Uint256 - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (balance) = carbonable_yielder_instance.total_locked(); - } - return (balance=balance,); - } - - func shares_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - address: felt, precision: felt - ) -> (shares: Uint256) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (shares) = carbonable_yielder_instance.shares_of( - address=address, precision=precision - ); - } - return (shares=shares,); - } - - func registred_owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (address: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_yielder { - let (address) = carbonable_yielder_instance.registred_owner_of( - token_id=token_id_uint256 - ); - } - return (address=address,); - } - - // Externals - - func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - with carbonable_project { - carbonable_project_instance.set_minter(minter=minter, caller=caller); - } - return (); - } - - func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - approved: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.approve( - approved=approved, token_id=token_id_uint256, caller=caller - ); - } - return (); - } - - func mint{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - to: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.mint(to=to, token_id=token_id_uint256, caller=caller); - } - return (); - } - - func start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unlocked_duration: felt, period_duration: felt - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (caller) = get_address(); - with carbonable_yielder { - let (success) = carbonable_yielder_instance.start_period( - unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller - ); - assert success = TRUE; - } - return (); - } - - func stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (caller) = get_address(); - with carbonable_yielder { - let (success) = carbonable_yielder_instance.stop_period(caller=caller); - assert success = TRUE; - } - return (); - } - - func deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - with carbonable_yielder { - let (success) = carbonable_yielder_instance.deposit( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_yielder; - } - return (); - } - - func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_yielder; - } - with carbonable_yielder { - let (success) = carbonable_yielder_instance.withdraw( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - return (); - } -} - -namespace anyone_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar anyone; - %{ ids.anyone = context.anyone_account_contract %} - return (anyone,); - } - - // Views - - func carbonable_project_address{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr - }() -> (carbonable_project_address: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let ( - carbonable_project_address - ) = carbonable_yielder_instance.carbonable_project_address(); - } - return (carbonable_project_address=carbonable_project_address,); - } - - func is_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - status: felt - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (status) = carbonable_yielder_instance.is_locked(); - } - return (status=status,); - } - - func total_locked{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> ( - balance: Uint256 - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (balance) = carbonable_yielder_instance.total_locked(); - } - return (balance=balance,); - } - - func shares_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - address: felt, precision: felt - ) -> (shares: Uint256) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - with carbonable_yielder { - let (shares) = carbonable_yielder_instance.shares_of( - address=address, precision=precision - ); - } - return (shares=shares,); - } - - func registred_owner_of{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - token_id: felt - ) -> (address: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_yielder { - let (address) = carbonable_yielder_instance.registred_owner_of( - token_id=token_id_uint256 - ); - } - return (address=address,); - } - - // Externals - - func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - approved: felt, token_id: felt - ) { - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - carbonable_project_instance.approve( - approved=approved, token_id=token_id_uint256, caller=caller - ); - } - return (); - } - - func start_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unlocked_duration: felt, period_duration: felt - ) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (caller) = get_address(); - with carbonable_yielder { - let (success) = carbonable_yielder_instance.start_period( - unlocked_duration=unlocked_duration, period_duration=period_duration, caller=caller - ); - assert success = TRUE; - } - return (); - } - - func stop_period{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (caller) = get_address(); - with carbonable_yielder { - let (success) = carbonable_yielder_instance.stop_period(caller=caller); - assert success = TRUE; - } - return (); - } - - func deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - with carbonable_yielder { - let (success) = carbonable_yielder_instance.deposit( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_yielder; - } - return (); - } - - func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(token_id: felt) { - let (carbonable_yielder) = carbonable_yielder_instance.deployed(); - let (carbonable_project) = carbonable_project_instance.deployed(); - let (caller) = get_address(); - let token_id_uint256 = Uint256(low=token_id, high=0); - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = carbonable_yielder; - } - with carbonable_yielder { - let (success) = carbonable_yielder_instance.withdraw( - token_id=token_id_uint256, caller=caller, carbonable_project=carbonable_project - ); - assert success = TRUE; - } - with carbonable_project { - let (owner) = carbonable_project_instance.ownerOf(tokenId=token_id_uint256); - assert owner = caller; - } - return (); - } -} From 056b5013602b11c03dd5bd59fd3cf6d64046a075 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Thu, 24 Nov 2022 13:59:00 +0100 Subject: [PATCH 6/8] =?UTF-8?q?=E2=9C=85=20fix=20protostar=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy_badge.yml | 2 +- .github/workflows/deploy_minter.yml | 2 +- .github/workflows/deploy_project.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/transfer_ownership.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy_badge.yml b/.github/workflows/deploy_badge.yml index 2cb25e6e..dfa7fb41 100644 --- a/.github/workflows/deploy_badge.yml +++ b/.github/workflows/deploy_badge.yml @@ -71,7 +71,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableBadge.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.8.0 + PROTOSTAR_VERSION: 0.8.1 jobs: deploy: diff --git a/.github/workflows/deploy_minter.yml b/.github/workflows/deploy_minter.yml index 243e11bb..d8549c6e 100644 --- a/.github/workflows/deploy_minter.yml +++ b/.github/workflows/deploy_minter.yml @@ -121,7 +121,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableMinter.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.8.0 + PROTOSTAR_VERSION: 0.8.1 jobs: deploy: diff --git a/.github/workflows/deploy_project.yml b/.github/workflows/deploy_project.yml index 284b4297..0bcde835 100644 --- a/.github/workflows/deploy_project.yml +++ b/.github/workflows/deploy_project.yml @@ -72,7 +72,7 @@ permissions: env: COMPILED_SOURCE: ./build/CarbonableProject.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.8.0 + PROTOSTAR_VERSION: 0.8.1 jobs: deploy: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 75e4871a..382f50de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,7 +3,7 @@ name: CI Tests on: [push, pull_request, pull_request_target] env: - PROTOSTAR_VERSION: 0.8.0 + PROTOSTAR_VERSION: 0.8.1 jobs: protostar-tests: diff --git a/.github/workflows/transfer_ownership.yml b/.github/workflows/transfer_ownership.yml index 451e2915..5f366b7a 100644 --- a/.github/workflows/transfer_ownership.yml +++ b/.github/workflows/transfer_ownership.yml @@ -73,7 +73,7 @@ permissions: env: PROJECT_ABI: ./build/CarbonableProject_abi.json PROTOSTAR_TOML_FILE: ./protostar.toml - PROTOSTAR_VERSION: 0.8.0 + PROTOSTAR_VERSION: 0.8.1 jobs: transfer: From f34029329d676142a3d4abb432225908de769639 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Thu, 24 Nov 2022 16:03:29 +0100 Subject: [PATCH 7/8] =?UTF-8?q?=E2=9C=85=20update=20test=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/__init__.py | 61 +++ tests/integrations/minter/config.yml | 6 - tests/integrations/minter/library.cairo | 471 ------------------ tests/integrations/protocol/library.cairo | 46 +- .../{minter => protocol}/test_minter.cairo | 2 +- 5 files changed, 101 insertions(+), 485 deletions(-) delete mode 100644 tests/integrations/minter/config.yml delete mode 100644 tests/integrations/minter/library.cairo rename tests/integrations/{minter => protocol}/test_minter.cairo (99%) diff --git a/tests/__init__.py b/tests/__init__.py index b0cfb0e6..d425acd8 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,6 @@ import yaml from pathlib import Path +from starkware.crypto.signature.fast_pedersen_hash import pedersen_hash class Object(): @@ -39,3 +40,63 @@ def load(path: str, context: object): # set up context context = objectify(context, config) + + +class MerkleTree: + + @staticmethod + def get_next_level(level): + next_level = [] + for i in range(0, len(level), 2): + node = 0 + if level[i] < level[i + 1]: + node = pedersen_hash(level[i], level[i + 1]) + else: + node = pedersen_hash(level[i + 1], level[i]) + next_level.append(node) + return next_level + + @staticmethod + def generate_proof_helper(level, index, proof): + if len(level) == 1: + return proof + if len(level) % 2 != 0: + level.append(0) + next_level = MerkleTree.get_next_level(level) + index_parent = 0 + for i in range(0, len(level)): + if i == index: + index_parent = i // 2 + if i % 2 == 0: + proof.append(level[index + 1]) + else: + proof.append(level[index - 1]) + return MerkleTree.generate_proof_helper(next_level, index_parent, proof) + + @staticmethod + def generate_merkle_proof(values, index): + return MerkleTree.generate_proof_helper(values, index, []) + + @staticmethod + def generate_merkle_root(values): + if len(values) == 1: + return values[0] + if len(values) % 2 != 0: + values.append(0) + next_level = MerkleTree.get_next_level(values) + return MerkleTree.generate_merkle_root(next_level) + + @staticmethod + def get_leaf(recipient, amount): + leaf = pedersen_hash(recipient, amount) + return leaf + + @staticmethod + def get_leaves(recipients, amounts): + values = [] + for recipient, amount in zip(recipients, amounts): + leaf = MerkleTree.get_leaf(recipient, amount) + values.append(leaf) + if len(values) % 2: + values.append(0) + return values diff --git a/tests/integrations/minter/config.yml b/tests/integrations/minter/config.yml deleted file mode 100644 index a19e8f97..00000000 --- a/tests/integrations/minter/config.yml +++ /dev/null @@ -1,6 +0,0 @@ -whitelist: - slots: 5 - merkle_root: 3236969588476960619958150604131083087415975923122021901088942336874683133579 - merkle_proof: - - 1489335374474017495857579265074565262713421005832572026644103123081435719307 - merkle_proof_len: 1 \ No newline at end of file diff --git a/tests/integrations/minter/library.cairo b/tests/integrations/minter/library.cairo deleted file mode 100644 index 0c2e7782..00000000 --- a/tests/integrations/minter/library.cairo +++ /dev/null @@ -1,471 +0,0 @@ -// SPDX-License-Identifier: MIT - -%lang starknet - -// Starkware dependencies -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.bool import TRUE, FALSE -from starkware.cairo.common.cairo_builtins import HashBuiltin -from starkware.cairo.common.uint256 import Uint256 - -// Project dependencies -from openzeppelin.token.erc20.IERC20 import IERC20 -from openzeppelin.token.erc721.IERC721 import IERC721 -from openzeppelin.token.erc721.enumerable.IERC721Enumerable import IERC721Enumerable -from openzeppelin.security.safemath.library import SafeUint256 - -// Local dependencies -from interfaces.minter import ICarbonableMinter -from interfaces.project import ICarbonableProject -from tests.integrations.protocol.library import ( - carbonable_project_instance, - payment_token_instance, - carbonable_minter_instance, -) - -// -// Functions -// - -func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - alloc_locals; - local merkle_root; - %{ - # Load config - import sys - sys.path.append('.') - from tests import load - load("./tests/integrations/minter/config.yml", context) - - # Carbonable project deployment - context.carbonable_project_class_hash = declare(contract=context.sources.project).class_hash - calldata = { - "name": context.project.name, - "symbol": context.project.symbol, - "owner": context.signers.admin, - "proxy_admin": context.signers.admin, - } - context.carbonable_project_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_project_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - - # Payment token deployment - context.payment_token_contract = deploy_contract( - contract=context.sources.token, - constructor_args={ - "name": context.token.name, - "symbol": context.token.symbol, - "decimals": context.token.decimals, - "initial_supply": context.token.initial_supply, - "recipient": context.signers.anyone - }, - ).contract_address - - # Carbonable minter deployment - context.carbonable_minter_class_hash = declare(contract=context.sources.minter).class_hash - calldata = { - "carbonable_project_address": context.carbonable_project_contract, - "payment_token_address": context.payment_token_contract, - "public_sale_open": context.minter.public_sale_open, - "max_buy_per_tx": context.minter.max_buy_per_tx, - "unit_price_low": context.minter.unit_price, - "unit_price_high": 0, - "max_supply_for_mint_low": context.minter.max_supply_for_mint, - "max_supply_for_mint_high": 0, - "reserved_supply_for_mint_low": context.minter.reserved_supply_for_mint, - "reserved_supply_for_mint_high": 0, - "owner": context.signers.admin, - "proxy_admin": context.signers.admin, - } - context.carbonable_minter_contract = deploy_contract( - contract=context.sources.proxy, - constructor_args={ - "implementation_hash": context.carbonable_minter_class_hash, - "selector": context.selector.initializer, - "calldata": calldata.values(), - } - ).contract_address - - # Externalize required variables - ids.merkle_root = context.whitelist.merkle_root - %} - - // Set minter and merkle root - let (local carbonable_minter) = carbonable_minter_instance.get_address(); - admin_instance.set_minter(carbonable_minter); - admin_instance.set_whitelist_merkle_root(merkle_root); - - return (); -} - -namespace admin_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar admin; - %{ ids.admin = context.signers.admin %} - return (admin,); - } - - // Externals - - func withdraw{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (payment_token) = payment_token_instance.get_address(); - let (caller) = get_address(); - with payment_token { - let (initial_balance) = payment_token_instance.balanceOf(account=caller); - let (contract_balance) = payment_token_instance.balanceOf(account=carbonable_minter); - } - with carbonable_minter { - let (success) = carbonable_minter_instance.withdraw(caller=caller); - assert success = TRUE; - } - with payment_token { - let (returned_balance) = payment_token_instance.balanceOf(account=caller); - let (expected_balance) = SafeUint256.add(initial_balance, contract_balance); - assert returned_balance = expected_balance; - } - return (); - } - - func set_whitelist_merkle_root{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - whitelist_merkle_root: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - carbonable_minter_instance.set_whitelist_merkle_root( - whitelist_merkle_root=whitelist_merkle_root, caller=caller - ); - let (returned_whitelist_merkle_root) = carbonable_minter_instance.whitelist_merkle_root( - ); - assert returned_whitelist_merkle_root = whitelist_merkle_root; - } - return (); - } - - func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - public_sale_open: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - carbonable_minter_instance.set_public_sale_open( - public_sale_open=public_sale_open, caller=caller - ); - let (returned_public_sale_open) = carbonable_minter_instance.public_sale_open(); - assert returned_public_sale_open = public_sale_open; - } - return (); - } - - func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - max_buy_per_tx: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - carbonable_minter_instance.set_max_buy_per_tx( - max_buy_per_tx=max_buy_per_tx, caller=caller - ); - let (returned_max_buy_per_tx) = carbonable_minter_instance.max_buy_per_tx(); - assert returned_max_buy_per_tx = max_buy_per_tx; - } - return (); - } - - func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unit_price: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - let unit_price_uint256 = Uint256(unit_price, 0); - with carbonable_minter { - carbonable_minter_instance.set_unit_price(unit_price=unit_price_uint256, caller=caller); - let (returned_unit_price) = carbonable_minter_instance.unit_price(); - assert returned_unit_price = unit_price_uint256; - } - return (); - } - - func decrease_reserved_supply_for_mint{ - syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr - }(slots: felt) { - alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - let slots_uint256 = Uint256(slots, 0); - with carbonable_minter { - let (initial_supply) = carbonable_minter_instance.reserved_supply_for_mint(); - carbonable_minter_instance.decrease_reserved_supply_for_mint( - slots=slots_uint256, caller=caller - ); - let (returned_supply) = carbonable_minter_instance.reserved_supply_for_mint(); - let (expected_supply) = SafeUint256.sub_le(initial_supply, slots_uint256); - assert returned_supply = expected_supply; - } - return (); - } - - func set_minter{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(minter: felt) { - let (carbonable_project) = carbonable_project_instance.get_address(); - let (caller) = get_address(); - with carbonable_project { - carbonable_project_instance.set_minter(minter=minter, caller=caller); - } - return (); - } - - func airdrop{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - to: felt, quantity: felt - ) { - alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (carbonable_project) = carbonable_project_instance.get_address(); - let (caller) = get_address(); - let quantity_uint256 = Uint256(quantity, 0); - - // get user nft and payment token balances to check after buy - with carbonable_project { - let (initial_quantity) = carbonable_project_instance.balanceOf(owner=to); - let (intial_total_supply) = carbonable_project_instance.totalSupply(); - } - - // make the user to buy the quantity - with carbonable_minter { - let (initial_reserved_supply) = carbonable_minter_instance.reserved_supply_for_mint(); - let (success) = carbonable_minter_instance.airdrop( - to=to, quantity=quantity, caller=caller - ); - assert success = TRUE; - let (expected_reserved_supply) = SafeUint256.sub_le( - initial_reserved_supply, quantity_uint256 - ); - let (returned_reserved_supply) = carbonable_minter_instance.reserved_supply_for_mint(); - assert expected_reserved_supply = returned_reserved_supply; - } - - // check total supply and user nft quantity after buy - with carbonable_project { - let (returned_total_supply) = carbonable_project_instance.totalSupply(); - let (expected_total_supply) = SafeUint256.sub_le( - returned_total_supply, intial_total_supply - ); - assert expected_total_supply = quantity_uint256; - - let (returned_quantity) = carbonable_project_instance.balanceOf(owner=to); - let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); - assert expected_quantity = quantity_uint256; - } - - return (); - } -} - -namespace anyone_instance { - // Internals - - func get_address() -> (address: felt) { - tempvar anyone; - %{ ids.anyone = context.signers.anyone %} - return (anyone,); - } - - func get_slots() -> (slots: felt) { - tempvar slots; - %{ ids.slots = context.whitelist.slots %} - return (slots,); - } - - func get_proof_len() -> (proof_len: felt) { - tempvar proof_len; - %{ ids.proof_len = context.whitelist.merkle_proof_len %} - return (proof_len,); - } - - func get_proof() -> (proof: felt*) { - alloc_locals; - let (local proof: felt*) = alloc(); - %{ - for index, node in enumerate(context.whitelist.merkle_proof): - memory[ids.proof + index] = node - %} - return (proof,); - } - - // Externals - - func set_public_sale_open{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - public_sale_open: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - carbonable_minter_instance.set_public_sale_open( - public_sale_open=public_sale_open, caller=caller - ); - let (returned_public_sale_open) = carbonable_minter_instance.public_sale_open(); - assert returned_public_sale_open = public_sale_open; - } - return (); - } - - func set_max_buy_per_tx{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - max_buy_per_tx: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - carbonable_minter_instance.set_max_buy_per_tx( - max_buy_per_tx=max_buy_per_tx, caller=caller - ); - let (returned_max_buy_per_tx) = carbonable_minter_instance.max_buy_per_tx(); - assert returned_max_buy_per_tx = max_buy_per_tx; - } - return (); - } - - func set_unit_price{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - unit_price: felt - ) { - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (caller) = get_address(); - let unit_price_uint256 = Uint256(unit_price, 0); - with carbonable_minter { - carbonable_minter_instance.set_unit_price(unit_price=unit_price_uint256, caller=caller); - let (returned_unit_price) = carbonable_minter_instance.unit_price(); - assert returned_unit_price = unit_price_uint256; - } - return (); - } - - func approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(quantity: felt) { - alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (payment_token) = payment_token_instance.get_address(); - let (caller) = get_address(); - with carbonable_minter { - let (unit_price) = carbonable_minter_instance.unit_price(); - let (allowance) = SafeUint256.mul(Uint256(quantity, 0), unit_price); - } - with payment_token { - let (success) = payment_token_instance.approve( - spender=carbonable_minter, amount=allowance, caller=caller - ); - assert success = TRUE; - let (returned_allowance) = payment_token_instance.allowance( - owner=caller, spender=carbonable_minter - ); - assert returned_allowance = allowance; - } - return (); - } - - func whitelist_buy{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - quantity: felt - ) { - alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (carbonable_project) = carbonable_project_instance.get_address(); - let (payment_token) = payment_token_instance.get_address(); - let (caller) = get_address(); - let (slots) = get_slots(); - let (proof_len) = get_proof_len(); - let (proof) = get_proof(); - - // get user nft and payment token balances to check after buy - with carbonable_project { - let (initial_quantity) = carbonable_project_instance.balanceOf(owner=caller); - let (intial_total_supply) = carbonable_project_instance.totalSupply(); - } - with payment_token { - let (initial_balance) = payment_token_instance.balanceOf(account=caller); - } - - // make the user to buy the quantity - with carbonable_minter { - let (whitelist_merkle_root) = carbonable_minter_instance.whitelist_merkle_root(); - let (unit_price) = carbonable_minter_instance.unit_price(); - let (success) = carbonable_minter_instance.whitelist_buy( - slots=slots, proof_len=proof_len, proof=proof, quantity=quantity, caller=caller - ); - assert success = TRUE; - } - - // check total supply and user nft quantity after buy - with carbonable_project { - let (returned_total_supply) = carbonable_project_instance.totalSupply(); - let (expected_total_supply) = SafeUint256.sub_le( - returned_total_supply, intial_total_supply - ); - assert expected_total_supply = Uint256(quantity, 0); - - let (returned_quantity) = carbonable_project_instance.balanceOf(owner=caller); - let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); - assert expected_quantity = Uint256(quantity, 0); - } - - // check user payment token balance after buy - with payment_token { - let (returned_balance) = payment_token_instance.balanceOf(account=caller); - let (expected_spend) = SafeUint256.sub_le(initial_balance, returned_balance); - let (spend) = SafeUint256.mul(Uint256(quantity, 0), unit_price); - assert expected_spend = spend; - } - return (); - } - - func public_buy{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}( - quantity: felt - ) { - alloc_locals; - let (carbonable_minter) = carbonable_minter_instance.get_address(); - let (carbonable_project) = carbonable_project_instance.get_address(); - let (payment_token) = payment_token_instance.get_address(); - let (caller) = get_address(); - - // get user nft and payment token balances to check after buy - with carbonable_project { - let (initial_quantity) = carbonable_project_instance.balanceOf(owner=caller); - let (intial_total_supply) = carbonable_project_instance.totalSupply(); - } - with payment_token { - let (initial_balance) = payment_token_instance.balanceOf(account=caller); - } - - // make the user to buy the quantity - with carbonable_minter { - let (unit_price) = carbonable_minter_instance.unit_price(); - let (success) = carbonable_minter_instance.public_buy(quantity=quantity, caller=caller); - assert success = TRUE; - } - - // check total supply and user nft quantity after buy - with carbonable_project { - let (returned_total_supply) = carbonable_project_instance.totalSupply(); - let (expected_total_supply) = SafeUint256.sub_le( - returned_total_supply, intial_total_supply - ); - assert expected_total_supply = Uint256(quantity, 0); - - let (returned_quantity) = carbonable_project_instance.balanceOf(owner=caller); - let (expected_quantity) = SafeUint256.sub_le(returned_quantity, initial_quantity); - assert expected_quantity = Uint256(quantity, 0); - } - - // check user payment token balance after buy - with payment_token { - let (returned_balance) = payment_token_instance.balanceOf(account=caller); - let (expected_spend) = SafeUint256.sub_le(initial_balance, returned_balance); - let (spend) = SafeUint256.mul(Uint256(quantity, 0), unit_price); - assert expected_spend = spend; - } - return (); - } -} diff --git a/tests/integrations/protocol/library.cairo b/tests/integrations/protocol/library.cairo index 41b0b794..35aea1ca 100644 --- a/tests/integrations/protocol/library.cairo +++ b/tests/integrations/protocol/library.cairo @@ -26,11 +26,12 @@ from interfaces.yielder import ICarbonableYielder func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { alloc_locals; + local merkle_root; %{ # Load config import sys sys.path.append('.') - from tests import load + from tests import load, MerkleTree load("./tests/integrations/minter/config.yml", context) # Admin account deployment @@ -74,7 +75,7 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { "symbol": context.token.symbol, "decimals": context.token.decimals, "initial_supply": context.token.initial_supply, - "recipient": context.signers.anyone + "recipient": context.anyone_account_contract }, ).contract_address @@ -134,13 +135,33 @@ func setup{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() { "calldata": calldata.values(), } ).contract_address + + # Build merkle tree + recipients = [context.anyone_account_contract, context.admin_account_contract] + slots = [5, 5] + merkle_leaves = MerkleTree.get_leaves(recipients, slots) + merkle_root = MerkleTree.generate_merkle_root(merkle_leaves) + merkle_proofs = [ + MerkleTree.generate_merkle_proof(merkle_leaves, index) + for index, _ in enumerate(recipients) + ] + + # Externalize required variables + context.whitelist = dict( + merkle_root=merkle_root, + merkle_proofs=merkle_proofs, + slots=slots, + recipients=recipients, + ) + ids.merkle_root = merkle_root %} - // Set minters + // Set minter and merkle root let (local admin_address) = admin_instance.get_address(); let (local carbonable_minter) = carbonable_minter_instance.get_address(); admin_instance.set_minter(admin_address); admin_instance.set_minter(carbonable_minter); + admin_instance.set_whitelist_merkle_root(merkle_root); return (); } @@ -1067,23 +1088,34 @@ namespace anyone_instance { } func get_slots() -> (slots: felt) { + let (address) = get_address(); tempvar slots; - %{ ids.slots = context.whitelist.slots %} + %{ + index = context.whitelist["recipients"].index(ids.address) + ids.slots = context.whitelist["slots"][index] + %} return (slots,); } func get_proof_len() -> (proof_len: felt) { + let (address) = get_address(); tempvar proof_len; - %{ ids.proof_len = context.whitelist.merkle_proof_len %} + %{ + index = context.whitelist["recipients"].index(ids.address) + ids.proof_len = len(context.whitelist["merkle_proofs"][index]) + %} return (proof_len,); } func get_proof() -> (proof: felt*) { alloc_locals; + let (address) = get_address(); let (local proof: felt*) = alloc(); %{ - for index, node in enumerate(context.whitelist.merkle_proof): - memory[ids.proof + index] = node + index = context.whitelist["recipients"].index(ids.address) + merkle_proof = context.whitelist["merkle_proofs"][index] + for idx, node in enumerate(merkle_proof): + memory[ids.proof + idx] = node %} return (proof,); } diff --git a/tests/integrations/minter/test_minter.cairo b/tests/integrations/protocol/test_minter.cairo similarity index 99% rename from tests/integrations/minter/test_minter.cairo rename to tests/integrations/protocol/test_minter.cairo index 9f4a9795..181a4bcb 100644 --- a/tests/integrations/minter/test_minter.cairo +++ b/tests/integrations/protocol/test_minter.cairo @@ -7,7 +7,7 @@ from starkware.cairo.common.bool import TRUE, FALSE from starkware.cairo.common.cairo_builtins import HashBuiltin // Local dependencies -from tests.integrations.minter.library import ( +from tests.integrations.protocol.library import ( setup, admin_instance as admin, anyone_instance as anyone, From 62408ade19806daa7eee5019ef7666eecaf9d943 Mon Sep 17 00:00:00 2001 From: bal7hazar Date: Thu, 24 Nov 2022 20:15:00 +0100 Subject: [PATCH 8/8] =?UTF-8?q?=E2=9C=85=20update=20CI=20scripts=20and=20c?= =?UTF-8?q?onfigs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protostar.toml | 9 +++- scripts/airdrop_badge.sh | 54 ------------------- scripts/configs/testnet.config | 28 +++++----- scripts/configs/testnet2.config | 20 +++++++ .../{deploy_project.sh => deploy_protocol.sh} | 9 ++-- scripts/generate_metadata.sh | 2 +- 6 files changed, 48 insertions(+), 74 deletions(-) delete mode 100755 scripts/airdrop_badge.sh create mode 100644 scripts/configs/testnet2.config rename scripts/{deploy_project.sh => deploy_protocol.sh} (88%) diff --git a/protostar.toml b/protostar.toml index 4a2ad077..db473d2c 100644 --- a/protostar.toml +++ b/protostar.toml @@ -1,5 +1,5 @@ [project] -protostar-version = "0.8.0" +protostar-version = "0.8.1" lib-path = "lib" cairo-path = ["./lib/cairopen_contracts/src", "./lib/cairo_contracts/src", "./lib/bal7hazar_contracts/src", "src"] @@ -23,5 +23,12 @@ private-key-path = "./.env" account-address = "0x063675fa1ecea10063722e61557ed7f49ed2503d6cdd74f4b31e9770b473650c" block-explorer = "starkscan" +[profile.testnet2.project] +gateway-url="https://alpha4-2.starknet.io" +chain-id=1536727068981429685321 +private-key-path = "./.env" +account-address = "0x063675fa1ecea10063722e61557ed7f49ed2503d6cdd74f4b31e9770b473650c" +block-explorer = "starkscan" + [profile.mainnet.project] network = "mainnet" diff --git a/scripts/airdrop_badge.sh b/scripts/airdrop_badge.sh deleted file mode 100755 index 5a85ae67..00000000 --- a/scripts/airdrop_badge.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -### CONSTANTS -SCRIPT_DIR=`readlink -f $0 | xargs dirname` -ROOT=`readlink -f $SCRIPT_DIR/..` -STARKNET_ACCOUNTS_FILE=$HOME/.starknet_accounts/starknet_open_zeppelin_accounts.json -PROTOSTAR_TOML_FILE=$ROOT/protostar.toml - -### FUNCTIONS -. $SCRIPT_DIR/library.sh # Logging utilities - -### RAW INPUTS -PROFILE="testnet" -BADGE_CONTRACT=0x00e3f53dd77369d98903828488de01d60a8e118cfc2e007d663aea6111da44ef -RECIPIENT_FILE=$ROOT/scripts/configs/recipients.txt -TOKEN_ID=0 -AMOUNT=1 - -### SETTINGS -CONFIG_FILE=$ROOT/scripts/configs/$PROFILE.config -[ -f $CONFIG_FILE ] && source $CONFIG_FILE || exit_error "$CONFIG_FILE file not found" - -[ -z $ADMIN_ADDRESS ] && ADMIN_ADDRESS=`get_account_address $ACCOUNT $STARKNET_ACCOUNTS_FILE` -[ -z $ADMIN_ADDRESS ] && exit_error "Unable to determine account address" - -[[ -z $NETWORK && ! -z $PROFILE ]] && NETWORK=`get_network $PROFILE $PROTOSTAR_TOML_FILE` -[ -z $NETWORK ] && exit_error "Unable to determine network" - -### PRE_CONDITIONS -check_wallet -check_starknet - -### LAST CHECK -print Profile: $PROFILE -print Account alias: $ACCOUNT -print Admin address: $ADMIN_ADDRESS -print Network: $NETWORK -print Badge contract: $BADGE_CONTRACT -print Recipients: $RECIPIENT_FILE -print Token ID: $TOKEN_ID -print AMOUNT: $AMOUNT -ask "Are you OK to airdrop with those parameters" || return - -### AIRDROP -token_id=$(felt_to_uint256 $TOKEN_ID) -amount=$(felt_to_uint256 $AMOUNT) -data_len=1 -data=0 -for to in $(cat $RECIPIENT_FILE); do - log_info "Mint $AMOUNT token (id=$TOKEN_ID) to $to" - send_transaction "starknet invoke --address $BADGE_CONTRACT --abi ./build/CarbonableBadge_abi.json --function mint --inputs $to $token_id $amount $data_len $data --network $NETWORK --account $ACCOUNT --wallet $WALLET" "$NETWORK" || exit_error -done - -exit_success \ No newline at end of file diff --git a/scripts/configs/testnet.config b/scripts/configs/testnet.config index 278baa88..3b64d5e7 100644 --- a/scripts/configs/testnet.config +++ b/scripts/configs/testnet.config @@ -2,19 +2,19 @@ ACCOUNT=carbonable WALLET=starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount -# ERC-1155 settings -ERC1155_URI="ipfs://bafybeid3s2i3rjqdxeaoi2du7r3yev4n25uzbwla7nyj5v22rwdl7lfvz4" -ERC1155_NAME="ERC-1155 Test" +# Carbonable Badge Settings +BADGE_URI="ipfs://bafybeid3s2i3rjqdxeaoi2du7r3yev4n25uzbwla7nyj5v22rwdl7lfvz4" +BADGE_NAME="Carbonable Badge Test" -# ERC-721 settings -ERC721_NAME="Carbonable ERC-721 Test" -ERC721_SYMBOL=CET -ERC721_URI="ipfs://bafybeihfuraj3mqqhn73ly2eap3ovxyu6ilasrmxpdg4hz7giul4hgr7zy" +# Carbonable Project Settings +PROJECT_NAME="Carbonable Project Test" +PROJECT_SYMBOL=CARB +PROJECT_URI="ipfs://bafybeigfdn34lppjksypyvmkeeim5536e77oj4jfsh62lbom2zu643rxbm" -# Minter settings -PAYMENT_TOKEN_ADDRESS=0x07394cbe418daa16e42b87ba67372d4ab4a5df0b05c6e554d158458ce245bc10 -PUBLIC_SALE_OPEN=1 -MAX_BUY_PER_TX=5 -UNIT_PRICE="10 0" -MAX_SUPPLY_FOR_MINT="10 0" -RESERVED_SUPPLY_FOR_MINT="3 0" \ No newline at end of file +# Carbonable Minter Settings +PAYMENT_TOKEN_ADDRESS=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 +MINTER_PUBLIC_SALE_OPEN=1 +MINTER_MAX_BUY_PER_TX=5 +MINTER_UNIT_PRICE="10 0" +MINTER_MAX_SUPPLY_FOR_MINT="10 0" +MINTER_RESERVED_SUPPLY_FOR_MINT="3 0" \ No newline at end of file diff --git a/scripts/configs/testnet2.config b/scripts/configs/testnet2.config new file mode 100644 index 00000000..3b64d5e7 --- /dev/null +++ b/scripts/configs/testnet2.config @@ -0,0 +1,20 @@ +# Global settings +ACCOUNT=carbonable +WALLET=starkware.starknet.wallets.open_zeppelin.OpenZeppelinAccount + +# Carbonable Badge Settings +BADGE_URI="ipfs://bafybeid3s2i3rjqdxeaoi2du7r3yev4n25uzbwla7nyj5v22rwdl7lfvz4" +BADGE_NAME="Carbonable Badge Test" + +# Carbonable Project Settings +PROJECT_NAME="Carbonable Project Test" +PROJECT_SYMBOL=CARB +PROJECT_URI="ipfs://bafybeigfdn34lppjksypyvmkeeim5536e77oj4jfsh62lbom2zu643rxbm" + +# Carbonable Minter Settings +PAYMENT_TOKEN_ADDRESS=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 +MINTER_PUBLIC_SALE_OPEN=1 +MINTER_MAX_BUY_PER_TX=5 +MINTER_UNIT_PRICE="10 0" +MINTER_MAX_SUPPLY_FOR_MINT="10 0" +MINTER_RESERVED_SUPPLY_FOR_MINT="3 0" \ No newline at end of file diff --git a/scripts/deploy_project.sh b/scripts/deploy_protocol.sh similarity index 88% rename from scripts/deploy_project.sh rename to scripts/deploy_protocol.sh index 056b1063..06a731e0 100755 --- a/scripts/deploy_project.sh +++ b/scripts/deploy_protocol.sh @@ -42,11 +42,12 @@ deploy_all_contracts() { [ ! -z $PROFILE ] && PROFILE_OPT="--profile $PROFILE" # Deploy ERC-721 token contract - if [ -z $ERC721_ADDRESS ]; then - erc721_name=$(str_to_hex "$ERC721_NAME") - erc721_symbol=$(str_to_hex "$ERC721_SYMBOL") + if [ -z $PROJECT_ADDRESS ]; then + project_name=$(str_to_hex "$PROJECT_NAME") + project_symbol=$(str_to_hex "$PROJECT_SYMBOL") log_info "Deploying ERC-721 contract..." - ERC721_ADDRESS=`send_transaction "protostar $PROFILE_OPT deploy ./build/CarbonableProject.json --inputs $erc721_name $erc721_symbol $ADMIN_ADDRESS" "$NETWORK"` || exit_error + PROJECT_CLASS_HASH=`send_transaction "protostar $PROFILE_OPT declare ./build/CarbonableProject.json --max-fee auto" "$NETWORK"` || exit_error + PROJECT_ADDRESS=`send_transaction "protostar $PROFILE_OPT deploy ./build/CarbonableProxy.json --max-fee auto --inputs $project_name $project_symbol $ADMIN_ADDRESS" "$NETWORK"` || exit_error fi # Deploy Minter contract diff --git a/scripts/generate_metadata.sh b/scripts/generate_metadata.sh index 06583924..540ce695 100755 --- a/scripts/generate_metadata.sh +++ b/scripts/generate_metadata.sh @@ -7,7 +7,7 @@ PARENT_DIR="$(dirname "$SOURCE_FILE")" ### GENERATION echo $TIMES -for (( i=0; i<$TIMES; i++)) +for (( i=1; i<=$TIMES; i++)) do cp $SOURCE_FILE $PARENT_DIR/$i.json done \ No newline at end of file