From b78a4cb50ffae378fecd06c9097722f24562d568 Mon Sep 17 00:00:00 2001 From: Nilesh Gupta Date: Sun, 23 Jun 2024 10:06:17 +0530 Subject: [PATCH] feat: added qwChild contract --- src/child/qwChild.cairo | 106 ++++++++++++++++++++++++++++++++++++++++ src/qwManager.cairo | 15 ++++-- src/qwRegistry.cairo | 9 ++-- 3 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 src/child/qwChild.cairo diff --git a/src/child/qwChild.cairo b/src/child/qwChild.cairo new file mode 100644 index 0000000..95c83c5 --- /dev/null +++ b/src/child/qwChild.cairo @@ -0,0 +1,106 @@ +use starknet::ContractAddress; + +#[starknet::interface] +trait IERC20 { + fn get_name(self: @T) -> felt252; + fn get_symbol(self: @T) -> felt252; + fn get_decimals(self: @T) -> u8; + fn get_total_supply(self: @T) -> u256; + fn balance_of(self: @T, account: ContractAddress) -> u256; + fn allowance(self: @T, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: T, recipient: ContractAddress, amount: u256); + fn transfer_from( + ref self: T, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ); + fn approve(ref self: T, spender: ContractAddress, amount: u256); + fn increase_allowance(ref self: T, spender: ContractAddress, added_value: u256); + fn decrease_allowance( + ref self: T, spender: ContractAddress, subtracted_value: u256 + ); +} + +#[starknet::interface] +trait IManager { + // Returns the registry address + fn getRegistry(self: @T) -> ContractAddress; + // Executes the investment + fn execute(ref self: T, targetQwChilds_: Array, tokenAddress_: Array, amount_: Array); + // Closes the investment + fn close(ref self: T, targetQwChilds_: Array, tokenAddress_: Array, amount_: Array); +} + +#[starknet::interface] +trait IChild { + // Executes the investment + fn create(ref self: T, tokenAddress_: ContractAddress, amount_: u256); + // Closes the investment + fn close(ref self: T, tokenAddress_: ContractAddress, amount_: u256); + // Returns the manager address + fn getManager(self: @T) -> ContractAddress; +} + +#[starknet::contract] +mod QwChild { + use starknet::{get_caller_address, ContractAddress, get_contract_address}; + use super::{IChildDispatcher, IChildDispatcherTrait}; + use super::{IManagerDispatcher, IManagerDispatcherTrait}; + use super::{IERC20Dispatcher, IERC20DispatcherTrait}; + + // ************************************************************************* + // STORAGE + // ************************************************************************* + #[storage] + struct Storage { + manager: IManagerDispatcher, + } + + // ************************************************************************* + // ERRORS + // ************************************************************************* + mod Errors { + const Invalid_Input_Length: felt252 = 'Invalid Input Length'; + const Contract_Not_Whitelisted: felt252 = 'Contract Not whitelisted'; + } + + // ************************************************************************* + // CONSTRUCTOR + // ************************************************************************* + #[constructor] + fn constructor(ref self: ContractState, manager_: ContractAddress) { + let managerContract = IManagerDispatcher { + contract_address: manager_ + }; + self.manager.write(managerContract); + } + + // ************************************************************************* + // EXTERNAL FUNCTIONS + // ************************************************************************* + #[abi(embed_v0)] + impl QwChild of super::IChild { + fn getManager(self: @ContractState) -> ContractAddress { + self.manager.read().contract_address + } + fn create(ref self: ContractState, tokenAddress_: ContractAddress, amount_: u256) { + let erc20Token = IERC20Dispatcher { + contract_address: tokenAddress_ + }; + + let manager_address = self.manager.read().contract_address; // Get the manager's address + let current_address = get_contract_address(); // Get the current contract's address + + erc20Token.transfer_from(manager_address, current_address, amount_); + } + + fn close(ref self: ContractState, tokenAddress_: ContractAddress, amount_: u256) { + let erc20Token = IERC20Dispatcher { + contract_address: tokenAddress_ + }; + + let manager_address = self.manager.read().contract_address; // Get the manager's address + let current_address = get_contract_address(); // Get the current contract's address + + erc20Token.transfer_from(manager_address, current_address, amount_); + } + } +} diff --git a/src/qwManager.cairo b/src/qwManager.cairo index 4ba1675..2da3ee5 100644 --- a/src/qwManager.cairo +++ b/src/qwManager.cairo @@ -21,8 +21,11 @@ trait IERC20 { #[starknet::interface] trait IManager { + // Returns the registry address + fn getRegistry(self: @T) -> ContractAddress; // Executes the investment fn execute(ref self: T, targetQwChilds_: Array, tokenAddress_: Array, amount_: Array); + // Closes the investment fn close(ref self: T, targetQwChilds_: Array, tokenAddress_: Array, amount_: Array); } @@ -35,9 +38,11 @@ trait IRegistry { #[starknet::interface] trait IChild { // Executes the investment - fn create(self: @T, tokenAddress_: ContractAddress, amount_: u256) -> ContractAddress; + fn create(ref self: T, tokenAddress_: ContractAddress, amount_: u256); // Closes the investment - fn close(self: @T, tokenAddress_: ContractAddress, amount_: u256) -> ContractAddress; + fn close(ref self: T, tokenAddress_: ContractAddress, amount_: u256); + // Returns the manager address + fn getManager(self: @T) -> ContractAddress; } #[starknet::contract] @@ -52,8 +57,7 @@ mod QwManager { // ************************************************************************* #[storage] struct Storage { - registry: IRegistryDispatcher, - whitelist: LegacyMap + registry: IRegistryDispatcher } // ************************************************************************* @@ -80,6 +84,9 @@ mod QwManager { // ************************************************************************* #[abi(embed_v0)] impl QwManager of super::IManager { + fn getRegistry(self: @ContractState) -> ContractAddress { + self.registry.read().contract_address + } fn execute(ref self: ContractState, targetQwChilds_: Array, tokenAddress_: Array, amount_: Array) { assert(targetQwChilds_.len() == tokenAddress_.len(), Errors::Invalid_Input_Length); assert(targetQwChilds_.len() == amount_.len(), Errors::Invalid_Input_Length); diff --git a/src/qwRegistry.cairo b/src/qwRegistry.cairo index 104adc5..a30927a 100644 --- a/src/qwRegistry.cairo +++ b/src/qwRegistry.cairo @@ -8,6 +8,8 @@ trait IRegistry { fn getIsChildWhitelisted(self: @T, child_: ContractAddress) -> bool; // Registers the child contract fn registerChild(ref self: T, child_: ContractAddress); + // Updates the manager address + fn updateManager(ref self: T, manager_: ContractAddress); } #[starknet::interface] @@ -56,15 +58,16 @@ mod QwRegistry { // CONSTRUCTOR // ************************************************************************* #[constructor] - fn constructor(ref self: ContractState, manager_: ContractAddress) { - self.manager.write(manager_); - } + fn constructor(ref self: ContractState) { } // ************************************************************************* // EXTERNAL FUNCTIONS // ************************************************************************* #[abi(embed_v0)] impl QwRegistry of super::IRegistry { + fn updateManager(ref self: ContractState, manager_: ContractAddress) { + self.manager.write(manager_); + } fn getManager(self: @ContractState) -> ContractAddress { self.manager.read() }