From 2c2f1c5636a040316b1bd47471691b9b85fc38ad Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 7 Sep 2023 03:12:47 +0200 Subject: [PATCH 01/40] Update EIP-7092: Move to Review --- EIPS/eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 6971b21604b79..8f3c84d4726f1 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -4,7 +4,7 @@ title: Financial Bonds description: This interface defines a specification for debt issued by corporations, goverments or other entities to investors in order to raise funds. author: Samuel Gwlanold Edoumou (@Edoumou) discussions-to: https://ethereum-magicians.org/t/financial-bonds/14461 -status: Draft +status: Review type: Standards Track category: ERC created: 2023-05-28 From 8ea969f76a6b7e98ed966915689d3a35f3cd02a7 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 7 Sep 2023 03:42:59 +0200 Subject: [PATCH 02/40] add balanceOf function and make principalOf function OPTIONAL --- EIPS/eip-7092.md | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 8f3c84d4726f1..bacdd296b7c4c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -150,11 +150,21 @@ interface IERC7092 { */ function dayCountBasis() external view returns(uint256); + /* + * @notice Returns the total supply + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. + */ + function totalSupply() external view returns(uint256); + + /** + * @notice Returns the balance of an account, i.e. the number of bond tokens owned by an account. + * @param _account account address + */ + function balanceOf(address _account) external view returns(uint256); + /** - * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...). - * NOTICE: The `principal` can also be expressed in `denomination` unit. In that case, the `principal` MUST equal the balance of `_account`. - * Ex: if denomination = $1,000, and the user has invested $5,000 (princiapl in currency unit), then - * principalOf(_account) = 5,000/1,000 = 5 + * @notice Returns the principal of an account. The principal MUST be expressed in the bond currency unit (USDC, DAI, etc...). + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. * @param _account account address */ function principalOf(address _account) external view returns(uint256); @@ -170,7 +180,7 @@ interface IERC7092 { /** * @notice Authorizes `_spender` account to manage `_amount`of their bonds * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to approve. _amount MUST be a multiple of denomination + * @param _amount amount of bond to approve. */ function approve(address _spender, uint256 _amount) external returns(bool); @@ -185,7 +195,7 @@ interface IERC7092 { /** * @notice Lower the allowance of `_spender` by `_amount` * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to remove approval; _amount MUST be a multiple of denomination + * @param _amount amount of bond to remove approval; */ function decreaseAllowance(address _spender, uint256 _amount) external returns(bool); @@ -200,7 +210,7 @@ interface IERC7092 { /** * @notice Moves `_amount` bonds to address `_to` * @param _to the address to send the bonds to - * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination + * @param _amount amount of bond to transfer. * @param _data additional information provided by the token holder */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); @@ -218,7 +228,7 @@ interface IERC7092 { * @notice Moves `_amount` bonds from an account that has authorized through the approve function * @param _from the bondholder address * @param _to the address to transfer bonds to - * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination + * @param _amount amount of bond to transfer. * @param _data additional information provided by the token holder */ function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); @@ -282,22 +292,21 @@ the `denomination`, and the `maturity date`. Those information are very importan ### Total Supply -We made the choice not to define the `totalSupply` function beacause it can be derived from both the `issue volume` and the `denomination`. -However it is RECOMMENDED to define the `totalSupply` function in any contract that implements this standard. In that case, -the `total supply` MUST be equal to the ratio of the `issue volume` and the `denomination`. +We made the choice to define the `totalSupply` function as OPTIONAL beacause it can be derived from both the `issue volume` and the `denomination`. +However in the case the `totalSupply` function is not dfefined in the interface, it is RECOMMENDED to define it in any contract that implements this standard. In that case, the `total supply` MUST be equal to the ratio of the `issue volume` and the `denomination`. ```javascript totalSupply = issueVolume / denomination ``` -### Account Balance +### Account Principal -Because the balance of an account can be derived from both the `principal` and the `denomination`, we made the choice not to define the `balanceOf` function. -However it is RECOMMENDED to define the `balanceOf` function in any contract that implements this standard. In that case, -the `balance` of an account MUST be equal to the ratio of the `principal` of that account and the `denomination`. +Because the principal of an account can be derived from both the `balance` and the `denomination`, we made the choice to make the `principalOf` function OPTIONAL. +However, when not defined in the interface it is RECOMMENDED to define the `principalOf` function in any contract that implements this standard. In that case, +the `princpal` of an account MUST be equal to the product of the `balance` of that account and the `denomination`. ```javascript - balanceOf(account) = principalOf(account) / denomination + principal(account) = balanceOf(account) * denomination ``` ## Backwards Compatibility From 1d767786b8991a672ebecc4c8f31e2cd805b8706 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:21:42 +0200 Subject: [PATCH 03/40] update EIP-7092 with cross-chain functionalities --- assets/eip-7092/IERC7092.sol | 200 +++++++++++++++++++++++++++++------ 1 file changed, 167 insertions(+), 33 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index bae6f376f8873..06cfe8aff894f 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -17,13 +17,17 @@ interface IERC7092 { /** * @notice Returns the bond symbol + * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date + * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function symbol() external view returns(string memory); /** * @notice Returns the number of decimals the bond uses - e.g `10`, means to divide the token amount by `10000000000` * - * OPTIONAL + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function decimals() external view returns(uint8); @@ -34,6 +38,8 @@ interface IERC7092 { /** * @notice Returns the copoun currency. This is the contract address of the token used to pay coupons. It can be same as the the one used for the principal + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function currencyOfCoupon() external view returns(address); @@ -45,11 +51,17 @@ interface IERC7092 { /** * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in denomination unit. - * ex: if denomination = $1,000, and the total debt is $5,000,000 - * then, issueVolume() = $5,000, 000 / $1,000 = 5,000 bonds */ function issueVolume() external view returns(uint256); + /** + * @notice Returns the total token supply + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used in case a bond needs to be represented as en ERC20 token. + * If not implemented, the total supply is equal to the ratio => issueVolume / denomination. + */ + function totalSupply() external view returns(uint256); + /** * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. * 1 basis point = 0.01% = 0.0001 @@ -59,12 +71,16 @@ interface IERC7092 { /** * @notice Returns the coupon type - * ex: 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... + * An example could be => 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function couponType() external view returns(uint256); /** * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. + * + * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function couponFrequency() external view returns(uint256); @@ -81,106 +97,224 @@ interface IERC7092 { /** * @notice Returns the day count basis - * Ex: 0: actual/actual, 1: actual/360, etc... + * An example could be => 0: actual/actual, 1: actual/360, etc... + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function dayCountBasis() external view returns(uint256); /** - * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in denomination unit. - * Ex: if denomination = $1,000, and the user has invested $5,000 - * then principalOf(_account) = 5,000/1,000 = 5 + * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...) * @param _account account address */ function principalOf(address _account) external view returns(uint256); + /** + * @notice returns the balance of `_account` + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used in case a bond needs to be represented as en ERC20 token. + * If not implemented, the balance of an account is equal to the ratio => principalOf(account) / denomination. + */ + function balanceOf(address _account) external view returns(uint256); + /** * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` * acount to manage their bonds * @param _owner the bondholder address * @param _spender the address that has been authorized by the bondholder */ - function approval(address _owner, address _spender) external view returns(uint256); + function allowance(address _owner, address _spender) external view returns(uint256); /** - * @notice Authorizes `_spender` account to manage `_amount`of their bonds + * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to approve. _amount MUST be a multiple of denomination + * @param _amount amount of bond tokens to approve */ - function approve(address _spender, uint256 _amount) external; + function approve(address _spender, uint256 _amount) external returns(bool); /** - * @notice Authorizes the `_spender` account to manage all their bonds + * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens in the destination Chain * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to approve + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. */ - function approveAll(address _spender) external; + function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Lowers the allowance of `_spender` by `_amount` * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to remove approval; _amount MUST be a multiple of denomination + * @param _amount amount of bond tokens to remove from allowance */ function decreaseAllowance(address _spender, uint256 _amount) external; /** - * @notice Removes the allowance for `_spender` - * @param _spender the address to remove the authorization by from + * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to remove from allowance + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. */ - function decreaseAllowanceForAll(address _spender) external; + function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; /** * @notice Moves `_amount` bonds to address `_to` * @param _to the address to send the bonds to - * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination + * @param _amount amount of bond tokens to transfer + */ + function transfer(address _to, uint256 _amount) external returns(bool); + + /** + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder */ - function transfer(address _to, uint256 _amount, bytes calldata _data) external; + function transferWithData(address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** - * @notice Moves all bonds to address `_to` + * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransfer(address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * This methods also allows to attach data to the token that is being transferred * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransferWithData(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * @param _from the bondholder address + * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer */ - function transferAll(address _to, bytes calldata _data) external; + function transferFrom(address _from, address _to, uint256 _amount) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred * @param _from the bondholder address * @param _to the address to transfer bonds to - * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination + * @param _amount amount of bond tokens to transfer. * @param _data additional information provided by the token holder */ - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; + function transferFromWithData(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** - * @notice Moves all bonds from `_from` to `_to`. The caller must have been authorized through the approve function + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * @param _from the bondholder address + * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransferFrom(address _from, address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * This methods also allows to attach data to the token that is being transferred * @param _from the bondholder address * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransferFromWithData(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice MUST be emitted when bond tokens are transferred + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred + */ + event Transfer(address _from, address _to, uint256 _amount); + + /** + * @notice MUST be emitted when bond tokens are transferred with additional data + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred * @param _data additional information provided by the token holder */ - function transferAllFrom(address _from, address _to, bytes calldata _data) external; + event TransferWithData(address _from, address _to, uint256 _amount, bytes _data); + + /** + * @notice MUST be emitted when bond tokens are transferred cross-chain + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + */ + event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract); /** - * @notice MUST be emitted when bonds are transferred + * @notice MUST be emitted when bond tokens are transferred cross-chain with additional data * @param _from the account that owns bonds * @param _to the account that receives the bond - * @param _amount the amount of bonds to be transferred + * @param _amount amount of bond tokens to be transferred * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. */ - event Transferred(address _from, address _to, uint256 _amount, bytes _data); + event CrossChainTransferWithData(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract); /** * @notice MUST be emitted when an account is approved * @param _owner the bonds owner * @param _spender the account to be allowed to spend bonds - * @param _amount the amount allowed by _owner to be spent by _spender. + * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. + */ + event Approval(address _owner, address _spender, uint256 _amount); + + /** + * @notice MUST be emitted when an account is approved cross-chain + * @param _owner the bonds owner + * @param _spender the account to be allowed to spend bonds + * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. */ - event Approved(address _owner, address _spender, uint256 _amount); + event CrossChainApproval(address _owner, address _spender, uint256 _amount); /** * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` * @param _owner the bonds owner * @param _spender the account that has been allowed to spend bonds - * @param _amount the amount of tokens to disapprove + * @param _amount amount of bond tokens to disapprove + */ + event DecreaseApproval(address _owner, address _spender, uint256 _amount); + + /** + * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` cross-chain + * @param _owner the bonds owner + * @param _spender the account that has been allowed to spend bonds + * @param _amount amount of bond tokens to disapprove + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. */ - event AllowanceDecreased(address _owner, address _spender, uint256 _amount); + event CrossChainDecreaseApproval(address _owner, address _spender, uint256 _amount); } From ad9b4e7374f920e6aa0376de312af8d790565cf6 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:20:54 +0200 Subject: [PATCH 04/40] update EIP7092 --- assets/eip-7092/IERC7092.sol | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 06cfe8aff894f..3d3d54b370aa7 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -174,7 +174,7 @@ interface IERC7092 { * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder */ - function transferWithData(address _to, uint256 _amount, bytes calldata _data) external returns(bool); + function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) @@ -198,7 +198,7 @@ interface IERC7092 { * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. */ - function crossChainTransferWithData(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function @@ -216,7 +216,7 @@ interface IERC7092 { * @param _amount amount of bond tokens to transfer. * @param _data additional information provided by the token holder */ - function transferFromWithData(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) @@ -242,10 +242,10 @@ interface IERC7092 { * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. */ - function crossChainTransferFromWithData(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice MUST be emitted when bond tokens are transferred + * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation * @param _from the account that owns bonds * @param _to the account that receives the bond * @param _amount amount of bond tokens to be transferred @@ -253,34 +253,13 @@ interface IERC7092 { event Transfer(address _from, address _to, uint256 _amount); /** - * @notice MUST be emitted when bond tokens are transferred with additional data - * @param _from the account that owns bonds - * @param _to the account that receives the bond - * @param _amount amount of bond tokens to be transferred - * @param _data additional information provided by the token holder - */ - event TransferWithData(address _from, address _to, uint256 _amount, bytes _data); - - /** - * @notice MUST be emitted when bond tokens are transferred cross-chain + * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain * @param _from the account that owns bonds * @param _to the account that receives the bond * @param _amount amount of bond tokens to be transferred * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - */ - event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract); - - /** - * @notice MUST be emitted when bond tokens are transferred cross-chain with additional data - * @param _from the account that owns bonds - * @param _to the account that receives the bond - * @param _amount amount of bond tokens to be transferred - * @param _data additional information provided by the token holder - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. */ - event CrossChainTransferWithData(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract); + event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); /** * @notice MUST be emitted when an account is approved From ab6292d8580e58c538e217c1329d468766edb253 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:28:43 +0200 Subject: [PATCH 05/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 3d3d54b370aa7..949c90c4d6f63 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -257,7 +257,7 @@ interface IERC7092 { * @param _from the account that owns bonds * @param _to the account that receives the bond * @param _amount amount of bond tokens to be transferred - * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationChainID The unique ID that identifies the destination Chain */ event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); @@ -273,11 +273,10 @@ interface IERC7092 { * @notice MUST be emitted when an account is approved cross-chain * @param _owner the bonds owner * @param _spender the account to be allowed to spend bonds - * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * @param _amount amount of bond tokens allowed by _owner to be spent by _spender + * @param _destinationChainID The unique ID that identifies the destination Chain */ - event CrossChainApproval(address _owner, address _spender, uint256 _amount); + event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); /** * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` @@ -292,8 +291,7 @@ interface IERC7092 { * @param _owner the bonds owner * @param _spender the account that has been allowed to spend bonds * @param _amount amount of bond tokens to disapprove - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * @param _destinationChainID The unique ID that identifies the destination Chain */ - event CrossChainDecreaseApproval(address _owner, address _spender, uint256 _amount); + event CrossChainDecreaseApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); } From add56957f258445c3e5f65086cfe11fc5d9677f5 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:55:43 +0200 Subject: [PATCH 06/40] Add batch transfer functions - IERC7092 --- assets/eip-7092/IERC7092.sol | 49 +++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 949c90c4d6f63..a33587388c523 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -176,6 +176,16 @@ interface IERC7092 { */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); + /** + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to array of addresses to send the bonds to + * @param _amount array of amount of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + */ + function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); + /** * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) * @param _to the address to send the bonds to @@ -194,12 +204,25 @@ interface IERC7092 { * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint bond tokens that are transferred. * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. */ function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * This methods also allows to attach data to the token that is being transferred + * @param _to array of addresses to send the bonds to + * @param _amount array of amounts of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * @param _destinationChainID array of unique IDs that identify the destination Chains. + * @param _destinationContract array of smart contracts to interact with in the destination Chains in order to Deposit or Mint bond tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function batchCrossChainTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function * @param _from the bondholder address @@ -218,6 +241,16 @@ interface IERC7092 { */ function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bond tokens to + * @param _amount array of amount of bond tokens to transfer. + * @param _data array of additional information provided by the token holder + */ + function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); + /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) * @param _from the bondholder address @@ -244,6 +277,20 @@ interface IERC7092 { */ function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bonds to + * @param _amount array of amount of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function batchCrossChainTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + /** * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation * @param _from the account that owns bonds From f9e1e12818b0734970c0b4f5e0fba06d3a0e89ac Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 16:36:31 +0200 Subject: [PATCH 07/40] Add batch functions - IERC7092 --- assets/eip-7092/IERC7092.sol | 101 +++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 21 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index a33587388c523..27855c20266bd 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -80,7 +80,7 @@ interface IERC7092 { /** * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. * - * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function couponFrequency() external view returns(uint256); @@ -143,6 +143,26 @@ interface IERC7092 { */ function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Authorizes several spenders account to manage `_amount`of their bond tokens + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to approve + * + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. + */ + function batchApprove(address[] calldata _spender, uint256[] calldata _amount) external returns(bool); + + /** + * @notice Authorizes several spender accounts to manage `_amount`of their bond tokens in the destination Chain + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to approve + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. + */ + function batchCrossChainApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + /** * @notice Lowers the allowance of `_spender` by `_amount` * @param _spender the address to be authorized by the bondholder @@ -161,6 +181,26 @@ interface IERC7092 { */ function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; + /** + * @notice Lowers the allowance of several spenders by corresponding amount in `_amount` + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to remove from allowance + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease token allowance. + */ + function batchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount) external; + + /** + * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to remove from allowance + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + */ + function batchCrossChainDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; + /** * @notice Moves `_amount` bonds to address `_to` * @param _to the address to send the bonds to @@ -176,16 +216,6 @@ interface IERC7092 { */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); - /** - * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred - * @param _to array of addresses to send the bonds to - * @param _amount array of amount of bond tokens to transfer - * @param _data array of additional information provided by the token holder - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. - */ - function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); - /** * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) * @param _to the address to send the bonds to @@ -210,6 +240,16 @@ interface IERC7092 { */ function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to array of addresses to send the bonds to + * @param _amount array of amount of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + */ + function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); + /** * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). * This methods also allows to attach data to the token that is being transferred @@ -241,16 +281,6 @@ interface IERC7092 { */ function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function - * This methods also allows to attach data to the token that is being transferred - * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bond tokens to - * @param _amount array of amount of bond tokens to transfer. - * @param _data array of additional information provided by the token holder - */ - function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); - /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) * @param _from the bondholder address @@ -277,6 +307,18 @@ interface IERC7092 { */ function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bond tokens to + * @param _amount array of amount of bond tokens to transfer. + * @param _data array of additional information provided by the token holder + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); + /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) * This methods also allows to attach data to the token that is being transferred @@ -299,6 +341,14 @@ interface IERC7092 { */ event Transfer(address _from, address _to, uint256 _amount); + /** + * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation + * @param _from array of accounts that owns bonds + * @param _to array of accounts that receives the bond + * @param _amount array of amount of bond tokens to be transferred + */ + event TransferBatch(address[] _from, address[] _to, uint256[] _amount); + /** * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain * @param _from the account that owns bonds @@ -308,6 +358,15 @@ interface IERC7092 { */ event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); + /** + * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred + * @param _destinationChainID The unique ID that identifies the destination Chain + */ + event CrossChainTransfer(address[] _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); + /** * @notice MUST be emitted when an account is approved * @param _owner the bonds owner From 2198298d82d33dbf341416a3fa2b81e24f9f4c8a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 16:42:13 +0200 Subject: [PATCH 08/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 27855c20266bd..5ae726b7c180a 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -215,17 +215,6 @@ interface IERC7092 { * @param _data additional information provided by the token holder */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) - * @param _to the address to send the bonds to - * @param _amount amount of bond tokens to transfer - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function crossChainTransfer(address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). @@ -280,18 +269,6 @@ interface IERC7092 { * @param _data additional information provided by the token holder */ function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) - * @param _from the bondholder address - * @param _to the address to transfer bonds to - * @param _amount amount of bond tokens to transfer - * @param _data additional information provided by the token holder - * @param _destinationChainID The unique ID that identifies the destination Chain - * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function crossChainTransferFrom(address _from, address _to, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) From 82eacc9430dd4549047736aa53ac3e2162fdbc3a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 16:59:51 +0200 Subject: [PATCH 09/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 50 ++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 5ae726b7c180a..d93531282e0c8 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -320,11 +320,11 @@ interface IERC7092 { /** * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation - * @param _from array of accounts that owns bonds + * @param _from bond token's owner * @param _to array of accounts that receives the bond * @param _amount array of amount of bond tokens to be transferred */ - event TransferBatch(address[] _from, address[] _to, uint256[] _amount); + event TransferBatch(address _from, address[] _to, uint256[] _amount); /** * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain @@ -337,16 +337,16 @@ interface IERC7092 { /** * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain - * @param _from the account that owns bonds - * @param _to the account that receives the bond - * @param _amount amount of bond tokens to be transferred - * @param _destinationChainID The unique ID that identifies the destination Chain + * @param _from the bond token's owner + * @param _to array of accounts that receive the bond + * @param _amount array of amount of bond tokens to be transferred + * @param _destinationChainID array of unique IDs that identify the destination Chain */ - event CrossChainTransfer(address[] _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); + event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); /** * @notice MUST be emitted when an account is approved - * @param _owner the bonds owner + * @param _owner bond token's owner * @param _spender the account to be allowed to spend bonds * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. */ @@ -361,6 +361,23 @@ interface IERC7092 { */ event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); + /** + * @notice MUST be emitted when a batch of accounts are approved + * @param _owner bond token's owner + * @param _spender array of accounts to be allowed to spend bonds + * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender. + */ + event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); + + /** + * @notice MUST be emitted when a batch of accounts are approved cross-chain + * @param _owner bond token's owner + * @param _spender array of accounts to be allowed to spend bonds + * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender + * @param _destinationChainID array of unique IDs that identify the destination Chain + */ + event CrossChainApprovalBatch(address _owner, address[] _spender, uint256[] _amount, uint64[] _destinationChainID); + /** * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` * @param _owner the bonds owner @@ -377,4 +394,21 @@ interface IERC7092 { * @param _destinationChainID The unique ID that identifies the destination Chain */ event CrossChainDecreaseApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); + + /** + * @notice MUST be emmitted when `_owner` decreases allowance from several sepnders by corresponding quantity in the array `_amount` + * @param _owner the bonds owner + * @param _spender array of accounts that had been allowed to spend bonds + * @param _amount array of amount of bond tokens to disapprove + */ + event DecreaseApprovalBatch(address _owner, address[] _spender, uint256[] _amount); + + /** + * @notice MUST be emmitted when the `_owner` decreases allowance from several sepnders by corresponding quantity in `_amount` cross-chain + * @param _owner the bonds owner + * @param _spender array of accounts that have been allowed to spend bonds + * @param _amount array of amount of bond tokens to disapprove + * @param _destinationChainID array of unique IDs that identify the destination Chain + */ + event CrossChainDecreaseApprovalBatch(address _owner, address _spender[], uint256 _amount[], uint64 _destinationChainID[]); } From 3f70fa68ff8db2739e9176de5a30989437ef1e3b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:10:54 +0200 Subject: [PATCH 10/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index d93531282e0c8..eb3f48c2eee3c 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -229,13 +229,22 @@ interface IERC7092 { */ function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves each amount of bond tokens in `_amount` to address corresponding address `_to`. + * @param _to array of addresses to send the bonds to + * @param _amount array of amount of bond tokens to transfer + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. + */ + function batchTransfer(address[] calldata _to, uint256[] calldata _amount) external returns(bool); + /** * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred * @param _to array of addresses to send the bonds to * @param _amount array of amount of bond tokens to transfer * @param _data array of additional information provided by the token holder * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); @@ -284,6 +293,17 @@ interface IERC7092 { */ function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bond tokens to + * @param _amount array of amount of bond tokens to transfer + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. + */ + function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount) external returns(bool); + /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function * This methods also allows to attach data to the token that is being transferred @@ -292,7 +312,7 @@ interface IERC7092 { * @param _amount array of amount of bond tokens to transfer. * @param _data array of additional information provided by the token holder * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); From 5d903b0caf0836a85351b1df84232bc6a9f9c653 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:20:49 +0200 Subject: [PATCH 11/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index eb3f48c2eee3c..1443ed69479b7 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -338,14 +338,6 @@ interface IERC7092 { */ event Transfer(address _from, address _to, uint256 _amount); - /** - * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation - * @param _from bond token's owner - * @param _to array of accounts that receives the bond - * @param _amount array of amount of bond tokens to be transferred - */ - event TransferBatch(address _from, address[] _to, uint256[] _amount); - /** * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain * @param _from the account that owns bonds @@ -355,6 +347,14 @@ interface IERC7092 { */ event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); + /** + * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation + * @param _from bond token's owner + * @param _to array of accounts that receives the bond + * @param _amount array of amount of bond tokens to be transferred + */ + event TransferBatch(address _from, address[] _to, uint256[] _amount); + /** * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain * @param _from the bond token's owner From 8210baef7c9d07566ba77ee52d56d3fdd65a5e1b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 01:54:15 +0200 Subject: [PATCH 12/40] Update eip-7092 - add REQUIRED functions --- EIPS/eip-7092.md | 131 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index bacdd296b7c4c..6911c5bcd80fd 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -15,7 +15,8 @@ created: 2023-05-28 This proposal introduces fixed income financial bonds. Important bond characteristics such as the International Securities Identification Number (ISIN), the issue volume, the issue date, the maturity date, the coupon rate, the coupon frequency, the principal, or the day count basis are defined to allow issuing bonds in the primary market (origination), and different transfer functions allow to buy or sell bonds in the secondary market. The standard also provides a -functionality to allow bonds to be approved by owners in order to be spent by third party. +functionality to allow bonds to be approved by owners in order to be spent by third party, and cross-chain functionalities that allow bond tokens of an issue to be +managed accross several blockchains. ## Motivation @@ -24,7 +25,7 @@ are considered more secured than equity since the issuer is supposed to repay th that are paid to investsors. This standard interface allows fixed income instruments to be represented as on-chain tokens, so as they can be managed through wallets, -and be used by applications like decentrailized exchanges. +and used by applications like decentrailized exchanges, digital platforms for investment banks, etc... The existing standard [ERC-3475](./eip-3475) that may be used to create abstract storage bonds does not follow same standards as with traditional bonds. By introducing concepts such as **classes** and **nonces** that are not used for traditional bonds, the ERC-3475 standard makes it difficult for @@ -49,6 +50,132 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S **Every contract compliant with the [ERC-7092](./eip-7092.md) MUST implement the following interface** +```solidity +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.8.0; + +/** +* @title ERC-7092 Financial Bonds tandard +*/ +interface IERC7092 { + /** + * @notice Returns the bond isin + */ + function isin() external view returns(string memory); + + /** + * @notice Returns the bond name + */ + function name() external view returns(string memory); + + /** + * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal + */ + function currency() external view returns(address); + + /** + * @notice Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unit of the principal currency + * ex: If the denomination is equal to 1,000 and the currency is USDC, then the bond denomination is equal to 1,000 USDC + */ + function denomination() external view returns(uint256); + + /** + * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in denomination unit. + */ + function issueVolume() external view returns(uint256); + + /** + * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. + * 1 basis point = 0.01% = 0.0001 + * ex: if interest rate = 5%, then coupon() => 500 basis points + */ + function couponRate() external view returns(uint256); + + /** + * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp + */ + function issueDate() external view returns(uint256); + + /** + * @notice Returns the bond maturity date, i.e, the date when the pricipal is repaid. This is a Unix Timestamp like the one returned by block.timestamp + * The maturity date MUST be greater than the issue date + */ + function maturityDate() external view returns(uint256); + + /** + * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...) + * @param _account account address + */ + function principalOf(address _account) external view returns(uint256); + + /** + * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` + * acount to manage their bonds + * @param _owner the bondholder address + * @param _spender the address that has been authorized by the bondholder + */ + function allowance(address _owner, address _spender) external view returns(uint256); + + /** + * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to approve + */ + function approve(address _spender, uint256 _amount) external returns(bool); + + /** + * @notice Lowers the allowance of `_spender` by `_amount` + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to remove from allowance + */ + function decreaseAllowance(address _spender, uint256 _amount) external; + + /** + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + */ + function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); + + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from the bondholder address + * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer. + * @param _data additional information provided by the token holder + */ + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); + + /** + * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred + */ + event Transfer(address _from, address _to, uint256 _amount); + + /** + * @notice MUST be emitted when an account is approved + * @param _owner bond token's owner + * @param _spender the account to be allowed to spend bonds + * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. + */ + event Approval(address _owner, address _spender, uint256 _amount); + + /** + * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` + * @param _owner the bonds owner + * @param _spender the account that has been allowed to spend bonds + * @param _amount amount of bond tokens to disapprove + */ + event DecreaseApproval(address _owner, address _spender, uint256 _amount); +} +``` + +### Optional Functions + ```solidity pragma solidity ^0.8.0; From 365ba002251dd3f04f6b17a62a733b1308a8898b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 02:15:54 +0200 Subject: [PATCH 13/40] Update IERC7092 - remove transfer functions without data param --- assets/eip-7092/IERC7092.sol | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 1443ed69479b7..3083c404b9731 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -201,13 +201,6 @@ interface IERC7092 { */ function batchCrossChainDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; - /** - * @notice Moves `_amount` bonds to address `_to` - * @param _to the address to send the bonds to - * @param _amount amount of bond tokens to transfer - */ - function transfer(address _to, uint256 _amount) external returns(bool); - /** * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred * @param _to the address to send the bonds to @@ -229,15 +222,6 @@ interface IERC7092 { */ function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); - /** - * @notice Moves each amount of bond tokens in `_amount` to address corresponding address `_to`. - * @param _to array of addresses to send the bonds to - * @param _amount array of amount of bond tokens to transfer - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. - */ - function batchTransfer(address[] calldata _to, uint256[] calldata _amount) external returns(bool); - /** * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred * @param _to array of addresses to send the bonds to @@ -261,14 +245,6 @@ interface IERC7092 { */ function batchCrossChainTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function - * @param _from the bondholder address - * @param _to the address to transfer bonds to - * @param _amount amount of bond tokens to transfer - */ - function transferFrom(address _from, address _to, uint256 _amount) external returns(bool); - /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function * This methods also allows to attach data to the token that is being transferred @@ -293,17 +269,6 @@ interface IERC7092 { */ function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function - * This methods also allows to attach data to the token that is being transferred - * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bond tokens to - * @param _amount array of amount of bond tokens to transfer - * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. - */ - function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount) external returns(bool); - /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function * This methods also allows to attach data to the token that is being transferred From 560caf63e85b8da65567ac714107ad09ec8f87b5 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 02:24:12 +0200 Subject: [PATCH 14/40] Update IERC7092 - Make symbol non optional --- assets/eip-7092/IERC7092.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 3083c404b9731..b0420f84f3959 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -19,8 +19,6 @@ interface IERC7092 { * @notice Returns the bond symbol * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function symbol() external view returns(string memory); From ccf80e06133dd1a3cb32791cb451997c63271100 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 03:39:31 +0200 Subject: [PATCH 15/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index b0420f84f3959..21214f1e99fbc 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -52,14 +52,6 @@ interface IERC7092 { */ function issueVolume() external view returns(uint256); - /** - * @notice Returns the total token supply - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used in case a bond needs to be represented as en ERC20 token. - * If not implemented, the total supply is equal to the ratio => issueVolume / denomination. - */ - function totalSupply() external view returns(uint256); - /** * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. * 1 basis point = 0.01% = 0.0001 @@ -107,14 +99,6 @@ interface IERC7092 { */ function principalOf(address _account) external view returns(uint256); - /** - * @notice returns the balance of `_account` - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used in case a bond needs to be represented as en ERC20 token. - * If not implemented, the balance of an account is equal to the ratio => principalOf(account) / denomination. - */ - function balanceOf(address _account) external view returns(uint256); - /** * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` * acount to manage their bonds From 0239fd5ba4b2e0b8a880a5688e1cd4806deaa939 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 04:09:48 +0200 Subject: [PATCH 16/40] Update eip-7092 - Add optional functions --- EIPS/eip-7092.md | 246 ++++++++++++----------------------------------- 1 file changed, 63 insertions(+), 183 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 6911c5bcd80fd..8ac2fed931b2c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -68,6 +68,13 @@ interface IERC7092 { */ function name() external view returns(string memory); + /** + * @notice Returns the bond symbol + * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date + * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` + */ + function symbol() external view returns(string memory); + /** * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal */ @@ -157,51 +164,21 @@ interface IERC7092 { event Transfer(address _from, address _to, uint256 _amount); /** - * @notice MUST be emitted when an account is approved + * @notice MUST be emitted when an account is approved or when the allowance is decreased * @param _owner bond token's owner * @param _spender the account to be allowed to spend bonds - * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. + * @param _amount amount of bond tokens allowed by _owner to be spent by `_spender` + * Or amount of bond tokens to decrease allowance from `_spender` */ event Approval(address _owner, address _spender, uint256 _amount); - - /** - * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` - * @param _owner the bonds owner - * @param _spender the account that has been allowed to spend bonds - * @param _amount amount of bond tokens to disapprove - */ - event DecreaseApproval(address _owner, address _spender, uint256 _amount); } ``` ### Optional Functions -```solidity -pragma solidity ^0.8.0; - -/** -* @title ERC-7092 Financial Bonds tandard -*/ -interface IERC7092 { - /** - * @notice Returns the bond isin - */ - function isin() external view returns(string memory); - - /** - * @notice Returns the bond name - */ - function name() external view returns(string memory); - - /** - * @notice Returns the bond symbol - * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date - * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function symbol() external view returns(string memory); +The following functions are optional. They MAY be used to improve the standard usability. +```solidity /** * @notice Returns the number of decimals the bond uses - e.g `10`, means to divide the token amount by `10000000000` * @@ -209,11 +186,6 @@ interface IERC7092 { */ function decimals() external view returns(uint8); - /** - * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal - */ - function currency() external view returns(address); - /** * @notice Returns the copoun currency. This is the contract address of the token used to pay coupons. It can be same as the the one used for the principal * @@ -221,31 +193,9 @@ interface IERC7092 { */ function currencyOfCoupon() external view returns(address); - /** - * @notice Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unnit of the principal currency - * ex: If the denomination is equal to 1,000 and the currency is USDC, then bond denomination is equal to 1,000 USDC - */ - function denomination() external view returns(uint256); - - /** - * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in the bond currency unit (USDC, DAI, etc...). - * NOTICE: The `issue volume` can also be expressed in `denomination` unit. In that case, the `issue volume` MUST equal the `totalSupply` - * of the bonds, i.e. the total number of bond tokens issued. - * ex: if denomination = $1,000, and the total debt is $5,000,000 - * then, issueVolume() = $5,000, 000 / $1,000 = 5,000 bonds - */ - function issueVolume() external view returns(uint256); - - /** - * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. - * 1 basis point = 0.01% = 0.0001 - * ex: if interest rate = 5%, then coupon() => 500 basis points - */ - function couponRate() external view returns(uint256); - /** * @notice Returns the coupon type - * ex: 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... + * An example could be => 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ @@ -254,147 +204,77 @@ interface IERC7092 { /** * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. * - * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function couponFrequency() external view returns(uint256); - /** - * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp - */ - function issueDate() external view returns(uint256); - - /** - * @notice Returns the bond maturity date, i.e, the date when the pricipal is repaid. This is a Unix Timestamp like the one returned by block.timestamp - * The` maturity date` MUST be greater than the `issue date` - */ - function maturityDate() external view returns(uint256); - /** * @notice Returns the day count basis - * Ex: 0: actual/actual, 1: actual/360, etc... + * An example could be => 0: actual/actual, 1: actual/360, etc... * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function dayCountBasis() external view returns(uint256); - /* - * @notice Returns the total supply - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function totalSupply() external view returns(uint256); - /** - * @notice Returns the balance of an account, i.e. the number of bond tokens owned by an account. - * @param _account account address - */ - function balanceOf(address _account) external view returns(uint256); - - /** - * @notice Returns the principal of an account. The principal MUST be expressed in the bond currency unit (USDC, DAI, etc...). - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - * @param _account account address - */ - function principalOf(address _account) external view returns(uint256); - - /** - * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` - * acount to manage their bonds - * @param _owner the bondholder address - * @param _spender the address that has been authorized by the bondholder - */ - function approval(address _owner, address _spender) external view returns(uint256); - - /** - * @notice Authorizes `_spender` account to manage `_amount`of their bonds - * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to approve. - */ - function approve(address _spender, uint256 _amount) external returns(bool); - - /** - * @notice Authorizes the `_spender` account to manage all their bonds - * @param _spender the address to be authorized by the bondholder + * @notice Authorizes several spenders account to manage `_amount`of their bond tokens + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to approve * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ - function approveAll(address _spender) external returns(bool); - - /** - * @notice Lower the allowance of `_spender` by `_amount` - * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond to remove approval; - */ - function decreaseAllowance(address _spender, uint256 _amount) external returns(bool); + function batchApprove(address[] calldata _spender, uint256[] calldata _amount) external returns(bool); /** - * @notice Remove the allowance for `_spender` - * @param _spender the address to remove the authorization by from + * @notice Lowers the allowance of several spenders by corresponding amount in `_amount` + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to remove from allowance * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function decreaseAllowanceForAll(address _spender) external returns(bool); - - /** - * @notice Moves `_amount` bonds to address `_to` - * @param _to the address to send the bonds to - * @param _amount amount of bond to transfer. - * @param _data additional information provided by the token holder + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease token allowance. */ - function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); + function batchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount) external; /** - * @notice Moves all bonds to address `_to` - * @param _to the address to send the bonds to - * @param _data additional information provided by the token holder + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to array of addresses to send the bonds to + * @param _amount array of amount of bond tokens to transfer + * @param _data array of additional information provided by the token holder * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function transferAll(address _to, bytes calldata _data) external returns(bool); + function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice Moves `_amount` bonds from an account that has authorized through the approve function - * @param _from the bondholder address - * @param _to the address to transfer bonds to - * @param _amount amount of bond to transfer. - * @param _data additional information provided by the token holder - */ - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); - - /** - * @notice Moves all bonds from `_from` to `_to`. The caller must have been authorized through the approve function - * @param _from the bondholder address - * @param _to the address to transfer bonds to - * @param _data additional information provided by the token holder + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bond tokens to + * @param _amount array of amount of bond tokens to transfer. + * @param _data array of additional information provided by the token holder * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function transferAllFrom(address _from, address _to, bytes calldata _data) external returns(bool); - - /** - * @notice MUST be emitted when bonds are transferred - * @param _from the account that owns bonds - * @param _to the account that receives the bond - * @param _amount the amount of bonds to be transferred - * @param _data additional information provided by the token holder + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - event Transferred(address _from, address _to, uint256 _amount, bytes _data); + function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice MUST be emitted when an account is approved - * @param _owner the bonds owner - * @param _spender the account to be allowed to spend bonds - * @param _amount the amount allowed by _owner to be spent by _spender. + * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation + * @param _from bond token's owner + * @param _to array of accounts that receives the bond + * @param _amount array of amount of bond tokens to be transferred + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchTransfer` and `batchTransferFrom` functions */ - event Approved(address _owner, address _spender, uint256 _amount); + event TransferBatch(address _from, address[] _to, uint256[] _amount); /** - * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` - * @param _owner the bonds owner - * @param _spender the account that has been allowed to spend bonds - * @param _amount the amount of tokens to disapprove + * @notice MUST be emitted when a batch of accounts are approved or when the allowance is removed from a batch of accounts + * @param _owner bond token's owner + * @param _spender array of accounts to be allowed to spend bonds + * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender. + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchApprove` and `batchDecreaseAllowance` functions */ - event AllowanceDecreased(address _owner, address _spender, uint256 _amount); -} + event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); ``` ## Rationale @@ -409,31 +289,31 @@ to list bonds, in that case, decentralized exchanges will be in charge of managi tokenized bonds by integrating this financial bond interface. The use of terminology such as `issueVolume` and `principalOf` instead of `totalSupply` and `balanceOf` respectively, as used in other standards like -[ERC-20](./eip-20) is motivated by the need to use same the terminology as with traditional bond. Furthermore, by adding the `data` input parameter +[ERC-20](./eip-20) is motivated by the need to use the same terminology as with traditional bonds. Furthermore, by adding the `data` input parameter in all `transfer` functions to allow the transfer of additional data, the ERC-7092 SHOULD NOT be compatible with the ERC-20 standard, even if both -the `principalOf` and `balanceOf` functions were used. +the `totalSupply` and `balanceOf` functions were used. Another reason that has motivated not to extend other standards like the ERC-20 is to allow token explorer platforms like etherscan to represent -the ERC-7092 token not as a simple ERC-20 token, but as a new token showing some bonds characteristics like the `principal`, the `coupon`, -the `denomination`, and the `maturity date`. Those information are very important for bondholders to know the return on the capital invested. +the ERC-7092 token not as a simple ERC-20 token, but as a new token showing in addition to the token balance, some bonds characteristics like the `interest rate` or `coupon rate`, +and the `maturity date`. Those information are very important for bondholders to know the return on the capital invested. ### Total Supply -We made the choice to define the `totalSupply` function as OPTIONAL beacause it can be derived from both the `issue volume` and the `denomination`. -However in the case the `totalSupply` function is not dfefined in the interface, it is RECOMMENDED to define it in any contract that implements this standard. In that case, the `total supply` MUST be equal to the ratio of the `issue volume` and the `denomination`. +We made the choice not to define the `totalSupply` function beacause it can be derived from both the `issueVolume` and the `denomination`. +However, it is RECOMMENDED to define it in any contract that implements this standard. The `total supply` MUST be equal to the ratio of the `issueVolume` and the `denomination`. ```javascript totalSupply = issueVolume / denomination ``` -### Account Principal +### Account Token Balance -Because the principal of an account can be derived from both the `balance` and the `denomination`, we made the choice to make the `principalOf` function OPTIONAL. -However, when not defined in the interface it is RECOMMENDED to define the `principalOf` function in any contract that implements this standard. In that case, -the `princpal` of an account MUST be equal to the product of the `balance` of that account and the `denomination`. +Because the token balance of an account can be derived from both the `principal` and the `denomination`, we made the choice not to define the `balanceOf` function. +However, it is RECOMMENDED to define the `balanceOf` function in any contract that implements this standard. The `balance` of an account MUST be equal to the ratio +of the `principal` of that account and the `denomination`. ```javascript - principal(account) = balanceOf(account) * denomination + balanceOf(account) = principalOf(account) / denomination ``` ## Backwards Compatibility From 432bfb90d50f3d7671baf569dda9863b3519bb26 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:39:30 +0200 Subject: [PATCH 17/40] Update eip-7092 - Add cross-chain functions --- EIPS/eip-7092.md | 138 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 8ac2fed931b2c..6dcf85e693aae 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -277,6 +277,144 @@ The following functions are optional. They MAY be used to improve the standard u event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); ``` +### Interoperability functionalities + +```solidity + /** + * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens in the destination Chain + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to approve + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. + */ + function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Authorizes several spender accounts to manage `_amount`of their bond tokens in the destination Chain + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to approve + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. + */ + function batchCrossChainApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + + /** + * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to remove from allowance + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + */ + function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; + + /** + * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @param _spender array of addresses to be authorized by the bondholder + * @param _amount array of amount of bond tokens to remove from allowance + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + */ + function batchCrossChainDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; + + /** + * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * This methods also allows to attach data to the token that is being transferred + * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint bond tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * This methods also allows to attach data to the token that is being transferred + * @param _to array of addresses to send the bonds to + * @param _amount array of amounts of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * @param _destinationChainID array of unique IDs that identify the destination Chains. + * @param _destinationContract array of smart contracts to interact with in the destination Chains in order to Deposit or Mint bond tokens that are transferred. + * + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function batchCrossChainTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * This methods also allows to attach data to the token that is being transferred + * @param _from the bondholder address + * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + * @param _destinationChainID The unique ID that identifies the destination Chain. + * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * This methods also allows to attach data to the token that is being transferred + * @param _from array of bondholder addresses + * @param _to array of addresses to transfer bonds to + * @param _amount array of amount of bond tokens to transfer + * @param _data array of additional information provided by the token holder + * @param _destinationChainID array of unique IDs that identifies the destination Chain. + * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + */ + function batchCrossChainTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + + /** + * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain + * @param _from the account that owns bonds + * @param _to the account that receives the bond + * @param _amount amount of bond tokens to be transferred + * @param _destinationChainID The unique ID that identifies the destination Chain + */ + event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); + + /** + * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain + * @param _from the bond token's owner + * @param _to array of accounts that receive the bond + * @param _amount array of amount of bond tokens to be transferred + * @param _destinationChainID array of unique IDs that identify the destination Chain + */ + event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); + + /** + * @notice MUST be emitted when an account is approved cross-chain + * @param _owner the bonds owner + * @param _spender the account to be allowed to spend bonds + * @param _amount amount of bond tokens allowed by _owner to be spent by _spender + * @param _destinationChainID The unique ID that identifies the destination Chain + */ + event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); + + /** + * @notice MUST be emitted when a batch of accounts are approved cross-chain + * @param _owner bond token's owner + * @param _spender array of accounts to be allowed to spend bonds + * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender + * @param _destinationChainID array of unique IDs that identify the destination Chain + */ + event CrossChainApprovalBatch(address _owner, address[] _spender, uint256[] _amount, uint64[] _destinationChainID); +``` + ## Rationale The financial bond standard is designed to represent fixed income assets, which reprensent a loan made by an investor to a borrower. From cc9d5c177a8f09c420c9c89a6d607c539329471a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 19:53:13 +0200 Subject: [PATCH 18/40] Update eip-7092 - implementing optional functions --- EIPS/eip-7092.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 6dcf85e693aae..b3b92e08ea810 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -176,7 +176,12 @@ interface IERC7092 { ### Optional Functions -The following functions are optional. They MAY be used to improve the standard usability. +The following functions are OPTIONAL. They MAY be used to improve the standard usability. + +- The `currencyOfCoupon` SHOULD be implemented only if the currency used for coupon payment is different from the currency used to repay the principal +- The `couponType` MAY be employed to signify the interest rate that the issuer has committed to paying to investors, which may take various forms such as zero coupon, fixed rate, floating rate, and more. +- The `couponFrequency` refers to how often the bond pays interest to its bondholders, and is typically expressed in terms of time periods, such as: Annual, Semi-Annual, Quarterly, or Monthly. +- The `dayCountBasis` is used to calculate the accrued interest on a bond between two coupon payment dates or other specific periods. Some of the day count basis are: Actual/Actual, 30/360, Actual/360, Actual/365, or 30/365 ```solidity /** @@ -199,7 +204,7 @@ The following functions are optional. They MAY be used to improve the standard u * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ - function couponType() external view returns(uint256); + function couponType() external view returns(uint8); /** * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. From d1083eeb49babdaa10f0bad9d106261a65f0fe3c Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 5 Oct 2023 20:21:32 +0200 Subject: [PATCH 19/40] Update eip-7092 - Add interoperability functions --- EIPS/eip-7092.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index b3b92e08ea810..7864cde661afe 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -182,6 +182,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u - The `couponType` MAY be employed to signify the interest rate that the issuer has committed to paying to investors, which may take various forms such as zero coupon, fixed rate, floating rate, and more. - The `couponFrequency` refers to how often the bond pays interest to its bondholders, and is typically expressed in terms of time periods, such as: Annual, Semi-Annual, Quarterly, or Monthly. - The `dayCountBasis` is used to calculate the accrued interest on a bond between two coupon payment dates or other specific periods. Some of the day count basis are: Actual/Actual, 30/360, Actual/360, Actual/365, or 30/365 +- Batch functions such as `batchApprove`, `batchTransfer` and more are used to optimize and streamline multiple operations into a single function call. This provide atomicity and gas usage optimization. ```solidity /** @@ -282,7 +283,16 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); ``` -### Interoperability functionalities +### Required functionas for Interoperability + +Interoperability is crucial for ERC standards that tokenize financial securities for several reasons: + +- Liquidity and Market Access: Interoperability enables bonds issued on a blockchain to be traded on various decentralized and centralized exchanges. +- Compliance and Regulatory Considerations: Different jurisdictions may have specific regulations and compliance requirements for financial bonds. Interoperability allows for the creation of bond tokens that can be compliant with various regulatory regimes. +- Cross-Asset and Cross-Chain Transfers: Interoperability can enable the movement of bonds between different blockchains. This is important because not all bonds or financial instruments may be tokenized on one blockchain alone. Interoperability allows for cross-chain transfers, making it possible to move bonds between different blockchain networks and ecosystems. +- Innovation and Collaboration: The ability for different projects, platforms, and ecosystems to work together fosters innovation and collaboration in the blockchain and financial technology space. Interoperability encourages developers and organizations to create complementary tools and services that enhance the bond token ecosystem. + +The following functions are REQUIRED to enable the management of bond tokens from the same issuance across multiple blockchain networks. ```solidity /** From d446bc7f06312edd9375f8ab1cd951427e565cba Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 04:53:38 +0200 Subject: [PATCH 20/40] Update eip-7092 --- EIPS/eip-7092.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 7864cde661afe..d428fe41937ba 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -283,7 +283,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); ``` -### Required functionas for Interoperability +### Required functions for Interoperability Interoperability is crucial for ERC standards that tokenize financial securities for several reasons: @@ -292,7 +292,8 @@ Interoperability is crucial for ERC standards that tokenize financial securities - Cross-Asset and Cross-Chain Transfers: Interoperability can enable the movement of bonds between different blockchains. This is important because not all bonds or financial instruments may be tokenized on one blockchain alone. Interoperability allows for cross-chain transfers, making it possible to move bonds between different blockchain networks and ecosystems. - Innovation and Collaboration: The ability for different projects, platforms, and ecosystems to work together fosters innovation and collaboration in the blockchain and financial technology space. Interoperability encourages developers and organizations to create complementary tools and services that enhance the bond token ecosystem. -The following functions are REQUIRED to enable the management of bond tokens from the same issuance across multiple blockchain networks. +The following functions are REQUIRED to enable the management of bond tokens of the same issuance across multiple blockchain networks. The standard presumes that any function initiating a cross-chain transaction must explicitly define the destination chain identifier `destinationChainID` and specify the target smart contract with which to interact on the destination blockchain, `destinationContract`. +The destination chain identifier should be the one specified by the cross-chain protocol in use.. One such protocol that can facilitate the implementation of cross-chain capabilities is the ChainLink Cross-Chain Interoperability Protocol (CCIP). ```solidity /** From e9313931070386fb0eaa734d5f213610d0cb4221 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 05:15:17 +0200 Subject: [PATCH 21/40] Update eip-7092 - Update the rationale --- EIPS/eip-7092.md | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index d428fe41937ba..3da378de281d9 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -293,7 +293,7 @@ Interoperability is crucial for ERC standards that tokenize financial securities - Innovation and Collaboration: The ability for different projects, platforms, and ecosystems to work together fosters innovation and collaboration in the blockchain and financial technology space. Interoperability encourages developers and organizations to create complementary tools and services that enhance the bond token ecosystem. The following functions are REQUIRED to enable the management of bond tokens of the same issuance across multiple blockchain networks. The standard presumes that any function initiating a cross-chain transaction must explicitly define the destination chain identifier `destinationChainID` and specify the target smart contract with which to interact on the destination blockchain, `destinationContract`. -The destination chain identifier should be the one specified by the cross-chain protocol in use.. One such protocol that can facilitate the implementation of cross-chain capabilities is the ChainLink Cross-Chain Interoperability Protocol (CCIP). +The destination chain identifier should be the one specified by the cross-chain protocol in use. One such protocol that can facilitate the implementation of cross-chain capabilities is the ChainLink Cross-Chain Interoperability Protocol (CCIP). ```solidity /** @@ -433,23 +433,19 @@ The destination chain identifier should be the one specified by the cross-chain ## Rationale -The financial bond standard is designed to represent fixed income assets, which reprensent a loan made by an investor to a borrower. -The proposed design has been motivated by the necessity to tokenize fixed income assets, and to represent the bond token with same -characteristics as in traditional finance. Keeping the same properties as in tradional finance is necessary for issuers and investors -to move to tokenized bonds without major difficulties. The same structure used in tradional finace, i.e issuer-investment bank-investors -can be used for the bond standard, in that case the investment bank intermediary may be replaced by smart contracts. In the case of -institutional issuance, the smart contracts can be managed by the investment bank. Decentralized exchanges may also use the bond standard -to list bonds, in that case, decentralized exchanges will be in charge of managing the smart contracts. Other entities may also create -tokenized bonds by integrating this financial bond interface. - -The use of terminology such as `issueVolume` and `principalOf` instead of `totalSupply` and `balanceOf` respectively, as used in other standards like -[ERC-20](./eip-20) is motivated by the need to use the same terminology as with traditional bonds. Furthermore, by adding the `data` input parameter -in all `transfer` functions to allow the transfer of additional data, the ERC-7092 SHOULD NOT be compatible with the ERC-20 standard, even if both -the `totalSupply` and `balanceOf` functions were used. - -Another reason that has motivated not to extend other standards like the ERC-20 is to allow token explorer platforms like etherscan to represent -the ERC-7092 token not as a simple ERC-20 token, but as a new token showing in addition to the token balance, some bonds characteristics like the `interest rate` or `coupon rate`, -and the `maturity date`. Those information are very important for bondholders to know the return on the capital invested. +The financial bond standard is specifically designed to represent fixed income assets, which essentially signify a loan provided by an investor to a borrower. The motivation behind this design stems from the need to tokenize fixed income assets and present the bond tokens with characteristics mirroring those found in traditional finance. Maintaining these familiar properties is essential for both issuers and investors, as it eases the transition to tokenized bonds without significant hurdles. + +The conventional finance structure, involving an issuer, an investment bank, and investors, can be seamlessly translated into the bond standard. In this context, smart contracts have the potential to replace the role of the investment bank intermediary. In cases of institutional issuance, the management of these smart contracts may be overseen by the investment bank. Additionally, decentralized exchanges can leverage the bond standard to list bonds, with the responsibility of managing the associated smart contracts falling on these decentralized exchange platforms. + +Furthermore, various other entities can utilize this financial bond interface to create tokenized bonds, integrating this standard into their operations. This adaptability and flexibility empower a wide range of participants within the financial ecosystem to benefit from the advantages of tokenized bonds while retaining the structure and processes they are familiar with from traditional finance. + +The choice of terminology, such as `issueVolume` and `principalOf` instead of `totalSupply` and `balanceOf` as found in other standards like [ERC-20](./eip-20), is deliberate and stems from the aim of aligning with the terminology commonly used in traditional bonds. This approach ensures consistency with traditional financial terminology, making it easier for users to relate to and understand the tokenized bonds. + +Moreover, the inclusion of a data input parameter in all transfer functions, which enables the transfer of additional data make the ERC-7092 not fully compatible with the ERC-20 standard. + +Another important motivation for not extending other standards like ERC-20 with ERC-7092 is to enable token explorer platforms like Etherscan to represent ERC-7092 tokens as distinct entities with unique characteristics. By doing so, these platforms can provide additional information beyond just token balances. This added information might include essential bond characteristics such as the `interest rate` or `coupon rate`, as well as the `maturity date`. + +The inclusion of these bond-specific details in token representations is highly valuable for bondholders and investors. It allows them to assess the return on their capital investment and make more informed decisions about their holdings. This level of transparency and specificity is crucial in the context of tokenized bonds, where investors rely on these details to evaluate the performance and risk associated with their investments. ### Total Supply From 29dd43b16dd27e125bf43c3ee0e852e2bf8a61f6 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 05:30:55 +0200 Subject: [PATCH 22/40] Update eip-7092 - balanceOf and totalSupply --- EIPS/eip-7092.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 3da378de281d9..b2bd5106280e2 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -449,8 +449,9 @@ The inclusion of these bond-specific details in token representations is highly ### Total Supply -We made the choice not to define the `totalSupply` function beacause it can be derived from both the `issueVolume` and the `denomination`. -However, it is RECOMMENDED to define it in any contract that implements this standard. The `total supply` MUST be equal to the ratio of the `issueVolume` and the `denomination`. +The decision not to explicitly define the `totalSupply` function in the ERC-7092 standard while providing a recommendation to implement it is a thoughtful approach. This choice acknowledges that the total supply of tokens in ERC-7092 can be derived from the `issueVolume` and the `denomination`, and it offers flexibility to developers. + +While the standard doesn't mandate the inclusion of the `totalSupply` function, it strongly recommends its implementation. When developers choose to include it, they should ensure that the total supply accurately represents the ratio of the issueVolume and the denomination. ```javascript totalSupply = issueVolume / denomination @@ -458,9 +459,7 @@ However, it is RECOMMENDED to define it in any contract that implements this sta ### Account Token Balance -Because the token balance of an account can be derived from both the `principal` and the `denomination`, we made the choice not to define the `balanceOf` function. -However, it is RECOMMENDED to define the `balanceOf` function in any contract that implements this standard. The `balance` of an account MUST be equal to the ratio -of the `principal` of that account and the `denomination`. +The ERC-7092 does not to explicitly define the balanceOf function, as the token balance can be calculated from both the `principal` and the `denomination`. However, it is strongly RECOMMENDED to consider including the `balanceOf` function when implementing this standard. When the `balanceOf` function is implemented, it should accurately reflect the token balance of an account as the ratio of the `principal` of that account and the `denomination`. ```javascript balanceOf(account) = principalOf(account) / denomination From bc77296dd9b12cfda55f8c43fbbee3b2e6694fde Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 05:56:07 +0200 Subject: [PATCH 23/40] Update eip-7092 - Embedded options --- EIPS/eip-7092.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index b2bd5106280e2..8c58134a078e3 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -465,27 +465,27 @@ The ERC-7092 does not to explicitly define the balanceOf function, as the token balanceOf(account) = principalOf(account) / denomination ``` -## Backwards Compatibility +## Backwards -Beacause some functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, -like [ERC-20](./eip-20) or [ERC-1155](./eip-1155). The ERC-7092 is a representation of a new token for bonds with all bonds characteristics -and functionalities already attached to it. +The ERC-7092 standard consciously deliberately avoids extending existing standards such as [ERC-20](./eip-20) or [ERC-1155](./eip-1155). This decision is motivated by the fact that some fundamental functions like `totalSupply` or `balanceOf` are not explicitly implemented in ERC-7092. + +Instead, the ERC-7092 standard is designed to stand on its own as a distinct representation of a new token specifically tailored for bonds. It encompasses all the essential bond characteristics and functionalities directly within its structure. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution -with other standards mentionned above SHOULD fail. +with other standards mentionned above SHOULD deviate from the standard. ## Reference Implementation The reference implementation of the [ERC-7092](./eip-7092.md) can be found [here](../assets/eip-7092/ERC7092.sol). -Some bonds have embedded options attached to them. As an example we can cite: +Certain bonds come with embedded options that enhance their flexibility and offer unique features. As an illustration: -1. Callable bonds that have an option that gives the issuer the right to retire bonds before they mature. -2. Puttable bonds that have an option that gives investors the right to retire bonds before they mature. -3. Convertible bonds that gives investors the right to convert their bonds to equity. +1.Callable bonds: These bonds grant the issuer the right, but not the obligation, to redeem or retire the bonds before their scheduled maturity date. This embedded call option provides issuers with the flexibility to reduce their debt obligations or take advantage of lower interest rates in the market by calling in and retiring the bonds when it becomes financially advantageous to do so. +2. Puttable bonds: These bonds provide investors with the right, but not the obligation, to sell the bonds back to the issuer or another specified entity before their scheduled maturity date. This embedded put option offers investors a degree of protection, allowing them to potentially receive their principal back before the maturity date if certain conditions are met. +3. Convertible bonds: They are a type of bond that comes with an embedded option, giving investors the right to convert their bonds into a specified number of common shares or equity securities of the issuer. This feature provides investors with the opportunity to participate in the potential future growth of the company issuing the bonds. -Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. +Bonds featuring embedded options can be generated by inheriting from the foundational ERC-7092 standard, which incorporates the ERC-7092 interface. This inheritance approach allows developers to build upon the base functionality of ERC-7092 while incorporating the specific features and logic required for bonds with embedded options. By extending the standard in this manner, developers can create specialized tokenized bond contracts that include the desired embedded option features, such as call options or put options. ### CALLABLE BONDS: From 65643f95c2d64fff712f3cb0247501ed535d9994 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 06:05:52 +0200 Subject: [PATCH 24/40] Update eip-7092 - Security Consideration --- EIPS/eip-7092.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 8c58134a078e3..9682df2974f46 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -465,7 +465,7 @@ The ERC-7092 does not to explicitly define the balanceOf function, as the token balanceOf(account) = principalOf(account) / denomination ``` -## Backwards +## Backwards Compatibility The ERC-7092 standard consciously deliberately avoids extending existing standards such as [ERC-20](./eip-20) or [ERC-1155](./eip-1155). This decision is motivated by the fact that some fundamental functions like `totalSupply` or `balanceOf` are not explicitly implemented in ERC-7092. @@ -570,7 +570,7 @@ contract ERC7092Convertible is ERC7092 { ## Security Considerations -When implementing the ERC-7092, it is important to consider security risk related to functions that give approval to operators to manage owner's bonds, and to functions that allow to transfer bonds. Functions `transferAll` and `transferAllFrom` allow to transfer all the balance of an account. Therefore, it is crucial to ensure that only the bonds owner and accounts that have been approved by the bonds owner can call these functions. +When implementing the ERC-7092 standard, it's of utmost importance to prioritize security and consider the associated risks, especially concerning functions that grant approval to operators for managing an owner's bonds and functions that enable bond transfers. Any mishandling or malicious actions in these functions can potentially result in the loss of bonds. To mitigate these risks, strict access control and authorization mechanisms should be in place. ## Copyright From fbf6ae2a25abbeda93836fe6a97fb59bcffbefff Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 06:14:18 +0200 Subject: [PATCH 25/40] Update eip-7092 - cross-chain batch --- EIPS/eip-7092.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 9682df2974f46..93f1bffe99092 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -316,7 +316,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. */ - function batchCrossChainApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain @@ -338,7 +338,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. */ - function batchCrossChainDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; + function crossChainBatchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; /** * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). @@ -364,7 +364,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. */ - function batchCrossChainTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) @@ -392,7 +392,7 @@ The destination chain identifier should be the one specified by the cross-chain * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. */ - function batchCrossChainTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain From 2523881ac8991e5fd6456bcc7d7cb5487441b852 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 06:49:54 +0200 Subject: [PATCH 26/40] Update eip-7092 - Identity registry --- EIPS/eip-7092.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 93f1bffe99092..e03caea674320 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -568,6 +568,12 @@ contract ERC7092Convertible is ERC7092 { } ``` +### Identity Registry + +The ERC-7092 standard, designed specifically for tokenizing bonds, focuses on functionalities related to bond origination and ownership transfer. It does not inherently manage information pertaining to bondholders' identities. However, to enhance compliance with regulatory requirements and improve transparency, it is strongly RECOMMENDED to implement an identity registry to store the identity addresses of all authorized investors. + +By maintaining an identity registry, issuers can ensure that bond tokens issued under the ERC-7092 standard are transferred only to registered and authorized entities. This practice aligns with regulatory compliance measures and provides a structured way to manage and verify the identity of bondholders. It also helps prevent unauthorized or non-compliant transfers of bond tokens. + ## Security Considerations When implementing the ERC-7092 standard, it's of utmost importance to prioritize security and consider the associated risks, especially concerning functions that grant approval to operators for managing an owner's bonds and functions that enable bond transfers. Any mishandling or malicious actions in these functions can potentially result in the loss of bonds. To mitigate these risks, strict access control and authorization mechanisms should be in place. From 9ba9f0dd57278a58505065ee04bdb94242f6cb56 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:23:22 +0200 Subject: [PATCH 27/40] Update BondStorage --- assets/eip-7092/BondStorage.sol | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index d68928ac5ed63..a8679af2530f8 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: CC0-1.0 -pragma solidity ^0.8.18; +pragma solidity ^0.8.0; + +// ["0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "Republique Francaise", "info@france.fr", "France", "GOV", "AA-", "1200"] contract BondStorage { struct Bond { @@ -7,27 +9,21 @@ contract BondStorage { string name; string symbol; address currency; - address currencyOfCoupon; - uint8 decimals; uint256 denomination; uint256 issueVolume; uint256 couponRate; - uint256 couponType; - uint256 couponFrequency; uint256 issueDate; uint256 maturityDate; - uint256 dayCountBasis; } struct Issuer { + address issuerAddress; string name; string email; string country; - string headquarters; string issuerType; string creditRating; uint256 carbonCredit; - address issuerAddress; } struct IssueData { @@ -37,13 +33,12 @@ contract BondStorage { enum BondStatus {UNREGISTERED, SUBMITTED, ISSUED, REDEEMED} - mapping(string => Bond) internal _bond; + mapping(string => Bond) internal _bonds; mapping(string => Issuer) internal _issuer; mapping(address => uint256) internal _principals; - mapping(address => mapping(address => uint256)) internal _approvals; + mapping(address => mapping(address => uint256)) internal _allowed; string internal bondISIN; - string internal _countryOfIssuance; BondStatus internal _bondStatus; IssueData[] internal _listOfInvestors; @@ -57,20 +52,4 @@ contract BondStorage { event BondIssued(IssueData[] _issueData, Bond _bond); event BondRedeemed(); - - function bondStatus() external view returns(BondStatus) { - return _bondStatus; - } - - function listOfInvestors() external view returns(IssueData[] memory) { - return _listOfInvestors; - } - - function bondInfo() public view returns(Bond memory) { - return _bond[bondISIN]; - } - - function issuerInfo() public view returns(Issuer memory) { - return _issuer[bondISIN]; - } } From efa5490e128781b8c3d7589b0fe997e4624774f9 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:23:40 +0200 Subject: [PATCH 28/40] Update BondStorage --- assets/eip-7092/BondStorage.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index a8679af2530f8..fe6ca89d37892 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; -// ["0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "Republique Francaise", "info@france.fr", "France", "GOV", "AA-", "1200"] - contract BondStorage { struct Bond { string isin; From 2512fb0589c6c3d7a64f11676efa8169ffb30988 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:24:46 +0200 Subject: [PATCH 29/40] Update ERC7092 --- assets/eip-7092/ERC7092.sol | 344 ++++++++++++++++++++---------------- 1 file changed, 191 insertions(+), 153 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index cf410ed8edb7c..ff0b3a5b6f9b7 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -4,9 +4,6 @@ pragma solidity ^0.8.0; import "./IERC7092.sol"; import "./BondStorage.sol"; -/** -* @notice Minimum implementation of the ERC7092 -*/ contract ERC7092 is IERC7092, BondStorage { constructor( string memory _bondISIN, @@ -28,125 +25,110 @@ contract ERC7092 is IERC7092, BondStorage { _redeem(_listOfInvestors); } - function _issue(IssueData[] memory _issueData, Bond memory _bondInfo) internal virtual { - uint256 volume; - uint256 _issueVolume = _bondInfo.issueVolume; - - for(uint256 i; i < _issueData.length; i++) { - address investor = _issueData[i].investor; - uint256 principal = _issueData[i].principal; - uint256 _denomination = _bondInfo.denomination; - - require(investor != address(0), "ERC7092: ZERO_ADDRESS_INVESTOR"); - require(principal != 0 && (principal * _denomination) % _denomination == 0, "ERC: INVALID_PRINCIPAL_AMOUNT"); - - volume += principal; - _principals[investor] = principal; - _listOfInvestors.push(IssueData({investor:investor, principal:principal})); - } - - _bond[bondISIN] = _bondInfo; - _bond[bondISIN].issueDate = block.timestamp; - _bondStatus = BondStatus.ISSUED; - - uint256 _maturityDate = _bond[bondISIN].maturityDate; - - require(_maturityDate > block.timestamp, "ERC7092: INVALID_MATURITY_DATE"); - require(volume == _issueVolume, "ERC7092: INVALID_ISSUE_VOLUME"); - - emit BondIssued(_issueData, _bondInfo); - } - - function _redeem(IssueData[] memory _bondsData) internal virtual { - uint256 _maturityDate = _bond[bondISIN].maturityDate; - require(block.timestamp > _maturityDate, "ERC2721: WAIT_MATURITY"); - - for(uint256 i; i < _bondsData.length; i++) { - if(_principals[_bondsData[i].investor] != 0) { - _principals[_bondsData[i].investor] = 0; - } - } - - _bondStatus = BondStatus.REDEEMED; - emit BondRedeemed(); - } - function isin() external view returns(string memory) { - return _bond[bondISIN].isin; + return _bonds[bondISIN].isin; } + /** + * @notice Returns the bond name + */ function name() external view returns(string memory) { - return _bond[bondISIN].name; + return _bonds[bondISIN].name; } + /** + * @notice Returns the bond symbol + * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date + * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` + */ function symbol() external view returns(string memory) { - return _bond[bondISIN].symbol; - } - - function decimals() external view returns(uint8) { - return _bond[bondISIN].decimals; + return _bonds[bondISIN].symbol; } + /** + * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal + */ function currency() external view returns(address) { - return _bond[bondISIN].currency; + return _bonds[bondISIN].currency; } - function currencyOfCoupon() external view returns(address) { - return _bond[bondISIN].currencyOfCoupon; - } - - function denomination() public view returns(uint256) { - return _bond[bondISIN].denomination; + /** + * @notice Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unit of the principal currency + * ex: If the denomination is equal to 1,000 and the currency is USDC, then the bond denomination is equal to 1,000 USDC + */ + function denomination() external view returns(uint256) { + return _bonds[bondISIN].denomination; } + /** + * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in denomination unit. + */ function issueVolume() external view returns(uint256) { - return _bond[bondISIN].issueVolume; + return _bonds[bondISIN].issueVolume; } - function couponRate() external view returns(uint256) { - return _bond[bondISIN].couponRate; + /** + * @notice Returns the bond tokens total supply + */ + function totalSupply() external view returns(uint256) { + return _bonds[bondISIN].issueVolume / _bonds[bondISIN].denomination; } - function couponType() external view returns(uint256) { - return _bond[bondISIN].couponType; - } - - function couponFrequency() external view returns(uint256) { - return _bond[bondISIN].couponFrequency; + /** + * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. + * 1 basis point = 0.01% = 0.0001 + * ex: if interest rate = 5%, then coupon() => 500 basis points + */ + function couponRate() external view returns(uint256) { + return _bonds[bondISIN].couponRate; } + /** + * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp + */ function issueDate() external view returns(uint256) { - return _bond[bondISIN].issueDate; - } - - function maturityDate() public view returns(uint256) { - return _bond[bondISIN].maturityDate; + return _bonds[bondISIN].issueDate; } - function dayCountBasis() external view returns(uint256) { - return _bond[bondISIN].dayCountBasis; + /** + * @notice Returns the bond maturity date, i.e, the date when the pricipal is repaid. This is a Unix Timestamp like the one returned by block.timestamp + * The maturity date MUST be greater than the issue date + */ + function maturityDate() external view returns(uint256) { + return _bonds[bondISIN].maturityDate; } + /** + * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...) + * @param _account account address + */ function principalOf(address _account) external view returns(uint256) { return _principals[_account]; } - function balanceOf(address _account) public view returns(uint256) { - require(_bondStatus == BondStatus.ISSUED, "ERC7092: NOT_ISSUED_OR_REDEEMED"); - - return _principals[_account] / _bond[bondISIN].denomination; - } - - function totalSupply() public view returns(uint256) { - require(_bondStatus == BondStatus.ISSUED, "ERC7092: NOT_ISSUED_OR_REDEEMED"); - - return _bond[bondISIN].issueVolume / _bond[bondISIN].denomination; + /** + * @notice Returns the balance of an account + * @param _account account address + */ + function balanceOf(address _account) external view returns(uint256) { + return _principals[_account] / _bonds[bondISIN].denomination; } - function approval(address _owner, address _spender) external view returns(uint256) { - return _approvals[_owner][_spender]; + /** + * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` + * acount to manage their bonds + * @param _owner the bondholder address + * @param _spender the address that has been authorized by the bondholder + */ + function allowance(address _owner, address _spender) external view returns(uint256) { + return _allowed[_owner][_spender]; } + /** + * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to approve + */ function approve(address _spender, uint256 _amount) external returns(bool) { address _owner = msg.sender; @@ -155,15 +137,11 @@ contract ERC7092 is IERC7092, BondStorage { return true; } - function approveAll(address _spender) external external returns(bool) { - address _owner = msg.sender; - uint256 _amount = _principals[_owner]; - - _approve(_owner, _spender, _amount); - - return true; - } - + /** + * @notice Lowers the allowance of `_spender` by `_amount` + * @param _spender the address to be authorized by the bondholder + * @param _amount amount of bond tokens to remove from allowance + */ function decreaseAllowance(address _spender, uint256 _amount) external returns(bool) { address _owner = msg.sender; @@ -172,70 +150,114 @@ contract ERC7092 is IERC7092, BondStorage { return true; } - function decreaseAllowanceForAll(address _spender) external returns(bool) { - address _owner = msg.sender; - uint256 _amount = _principals[_owner]; + /** + * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @param _to the address to send the bonds to + * @param _amount amount of bond tokens to transfer + * @param _data additional information provided by the token holder + */ + function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool) { + address _from = msg.sender; - _decreaseAllowance(_owner, _spender, _amount); + _transfer(_from, _to, _amount, _data); return true; } - function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool) { - address _from = msg.sender; + /** + * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * This methods also allows to attach data to the token that is being transferred + * @param _from the bondholder address + * @param _to the address to transfer bonds to + * @param _amount amount of bond tokens to transfer. + * @param _data additional information provided by the token holder + */ + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool) { + address _spender = msg.sender; + + _spendAllowance(_from, _spender, _amount); _transfer(_from, _to, _amount, _data); return true; } - function transferAll(address _to, bytes calldata _data) external returns(bool) { - address _from = msg.sender; - uint256 _amount = _principals[_from]; + function bondStatus() external view returns(BondStatus) { + return _bondStatus; + } - _transfer(_from, _to, _amount, _data); + function listOfInvestors() external view returns(IssueData[] memory) { + return _listOfInvestors; + } - return true; + function bondInfo() public view returns(Bond memory) { + return _bonds[bondISIN]; + } + + function issuerInfo() public view returns(Issuer memory) { + return _issuer[bondISIN]; } - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool) { - address _spender = msg.sender; + function _issue(IssueData[] memory _issueData, Bond memory _bondInfo) internal virtual { + uint256 volume; + uint256 _issueVolume = _bondInfo.issueVolume; + + for(uint256 i; i < _issueData.length; i++) { + address investor = _issueData[i].investor; + uint256 principal = _issueData[i].principal; + uint256 _denomination = _bondInfo.denomination; + + require(investor != address(0), "ERC7092: ZERO_ADDRESS_INVESTOR"); + require(principal != 0 && (principal * _denomination) % _denomination == 0, "ERC: INVALID_PRINCIPAL_AMOUNT"); - _spendApproval(_from, _spender, _amount); + volume += principal; + _principals[investor] = principal; + _listOfInvestors.push(IssueData({investor:investor, principal:principal})); + } + + _bonds[bondISIN] = _bondInfo; + _bonds[bondISIN].issueDate = block.timestamp; + _bondStatus = BondStatus.ISSUED; - _transfer(_from, _to, _amount, _data); + uint256 _maturityDate = _bonds[bondISIN].maturityDate; - return true; - } + require(_maturityDate > block.timestamp, "ERC7092: INVALID_MATURITY_DATE"); + require(volume == _issueVolume, "ERC7092: INVALID_ISSUE_VOLUME"); - function transferAllFrom(address _from, address _to, bytes calldata _data) external returns(bool) { - address _spender = msg.sender; - uint256 _amount = _principals[_from]; + emit BondIssued(_issueData, _bondInfo); + } - _spendApproval(_from, _spender, _amount); + function _redeem(IssueData[] memory _bondsData) internal virtual { + uint256 _maturityDate = _bonds[bondISIN].maturityDate; + require(block.timestamp > _maturityDate, "ERC2721: WAIT_MATURITY"); - _transfer(_from, _to, _amount, _data); + for(uint256 i; i < _bondsData.length; i++) { + if(_principals[_bondsData[i].investor] != 0) { + _principals[_bondsData[i].investor] = 0; + } + } - return true; + _bondStatus = BondStatus.REDEEMED; + emit BondRedeemed(); } function _approve(address _owner, address _spender, uint256 _amount) internal virtual { require(_owner != address(0), "ERC7092: OWNER_ZERO_ADDRESS"); require(_spender != address(0), "ERC7092: SPENDER_ZERO_ADDRESS"); require(_amount > 0, "ERC7092: INVALID_AMOUNT"); + require(block.timestamp < _bonds[bondISIN].maturityDate, "ERC7092: BONDS_MATURED"); - uint256 principal = _principals[_owner]; - uint256 _approval = _approvals[_owner][_spender]; - uint256 _denomination = denomination(); - uint256 _maturityDate = maturityDate(); + uint256 _balance = _principals[_owner] / _bonds[bondISIN].denomination; + uint256 _denomination = _bonds[bondISIN].denomination; - require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); - require(_amount <= principal, "ERC7092: INSUFFICIENT_BALANCE"); - require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + require(_amount <= _balance, "ERC7092: INSUFFICIENT_BALANCE"); + require((_amount * _denomination) % _denomination == 0, "ERC7092: INVALID_AMOUNT"); - _approvals[_owner][_spender] = _approval + _amount; + uint256 _approval = _allowed[_owner][_spender]; - emit Approved(_owner, _spender, _amount); + _allowed[_owner][_spender] = _approval + _amount; + + emit Approval(_owner, _spender, _amount); } function _decreaseAllowance(address _owner, address _spender, uint256 _amount) internal virtual { @@ -243,56 +265,72 @@ contract ERC7092 is IERC7092, BondStorage { require(_spender != address(0), "ERC7092: SPENDER_ZERO_ADDRESS"); require(_amount > 0, "ERC7092: INVALID_AMOUNT"); - uint256 _approval = _approvals[_owner][_spender]; - uint256 _denomination = denomination(); - uint256 _maturityDate = maturityDate(); + uint256 _allowance = _allowed[_owner][_spender]; + uint256 _denomination = _bonds[bondISIN].denomination; - require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); - require(_amount <= _approval, "ERC7092: NOT_ENOUGH_APPROVAL"); - require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + require(block.timestamp < _bonds[bondISIN].maturityDate, "ERC7092: BONDS_MATURED"); + require(_amount <= _allowance, "ERC7092: NOT_ENOUGH_APPROVAL"); + require((_amount * _denomination) % _denomination == 0, "ERC7092: INVALID_AMOUNT"); - _approvals[_owner][_spender] = _approval - _amount; + _allowed[_owner][_spender] = _allowance - _amount; - emit AllowanceDecreased(_owner, _spender, _amount); + emit Approval(_owner, _spender, _amount); } - function _transfer(address _from, address _to, uint256 _amount, bytes calldata _data) internal virtual { + function _transfer( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) internal virtual { require(_from != address(0), "ERC7092: OWNER_ZERO_ADDRESS"); require(_to != address(0), "ERC7092: SPENDER_ZERO_ADDRESS"); require(_amount > 0, "ERC7092: INVALID_AMOUNT"); uint256 principal = _principals[_from]; - uint256 _denomination = denomination(); - uint256 _maturityDate = maturityDate(); + uint256 _denomination = _bonds[bondISIN].denomination; + uint256 _balance = principal / _denomination; - require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); - require(_amount <= principal, "ERC7092: INSUFFICIENT_BALANCE"); - require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + require(block.timestamp < _bonds[bondISIN].maturityDate, "ERC7092: BONDS_MATURED"); + require(_amount <= _balance, "ERC7092: INSUFFICIENT_BALANCE"); + require((_amount * _denomination) % _denomination == 0, "ERC7092: INVALID_AMOUNT"); _beforeBondTransfer(_from, _to, _amount, _data); uint256 principalTo = _principals[_to]; unchecked { - _principals[_from] = principal - _amount; - _principals[_to] = principalTo + _amount; + uint256 _principalToTransfer = _amount * _denomination; + + _principals[_from] = principal - _principalToTransfer; + _principals[_to] = principalTo + _principalToTransfer; } - emit Transferred(_from, _to, _amount, _data); + emit Transfer(_from, _to, _amount); _afterBondTransfer(_from, _to, _amount, _data); } - function _spendApproval(address _from, address _spender, uint256 _amount) internal virtual { - uint256 currentApproval = _approvals[_from][_spender]; - require(_amount <= currentApproval, "ERC7092: INSUFFICIENT_ALLOWANCE"); + function _spendAllowance(address _from, address _spender, uint256 _amount) internal virtual { + uint256 currentAllowance = _allowed[_from][_spender]; + require(_amount <= currentAllowance, "ERC7092: INSUFFICIENT_ALLOWANCE"); unchecked { - _approvals[_from][_spender] = currentApproval - _amount; + _allowed[_from][_spender] = currentAllowance - _amount; } } - function _beforeBondTransfer(address _from, address _to, uint256 _amount, bytes calldata _data) internal virtual {} - - function _afterBondTransfer(address _from, address _to, uint256 _amount, bytes calldata _data) internal virtual {} + function _beforeBondTransfer( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) internal virtual {} + + function _afterBondTransfer( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) internal virtual {} } From fd3e208458edce7341ad0613765e8033051d1dce Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:28:38 +0200 Subject: [PATCH 30/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 268 +---------------------------------- 1 file changed, 4 insertions(+), 264 deletions(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 21214f1e99fbc..68641994e6c20 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -22,25 +22,11 @@ interface IERC7092 { */ function symbol() external view returns(string memory); - /** - * @notice Returns the number of decimals the bond uses - e.g `10`, means to divide the token amount by `10000000000` - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function decimals() external view returns(uint8); - /** * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal */ function currency() external view returns(address); - /** - * @notice Returns the copoun currency. This is the contract address of the token used to pay coupons. It can be same as the the one used for the principal - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function currencyOfCoupon() external view returns(address); - /** * @notice Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unit of the principal currency * ex: If the denomination is equal to 1,000 and the currency is USDC, then the bond denomination is equal to 1,000 USDC @@ -59,21 +45,6 @@ interface IERC7092 { */ function couponRate() external view returns(uint256); - /** - * @notice Returns the coupon type - * An example could be => 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function couponType() external view returns(uint256); - - /** - * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function couponFrequency() external view returns(uint256); - /** * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp */ @@ -85,14 +56,6 @@ interface IERC7092 { */ function maturityDate() external view returns(uint256); - /** - * @notice Returns the day count basis - * An example could be => 0: actual/actual, 1: actual/360, etc... - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function dayCountBasis() external view returns(uint256); - /** * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...) * @param _account account address @@ -114,74 +77,12 @@ interface IERC7092 { */ function approve(address _spender, uint256 _amount) external returns(bool); - /** - * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens in the destination Chain - * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond tokens to approve - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. - */ - function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); - - /** - * @notice Authorizes several spenders account to manage `_amount`of their bond tokens - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to approve - * - * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. - */ - function batchApprove(address[] calldata _spender, uint256[] calldata _amount) external returns(bool); - - /** - * @notice Authorizes several spender accounts to manage `_amount`of their bond tokens in the destination Chain - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to approve - * @param _destinationChainID array of unique IDs that identifies the destination Chain. - * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. - */ - function batchCrossChainApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); - /** * @notice Lowers the allowance of `_spender` by `_amount` * @param _spender the address to be authorized by the bondholder * @param _amount amount of bond tokens to remove from allowance */ - function decreaseAllowance(address _spender, uint256 _amount) external; - - /** - * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain - * @param _spender the address to be authorized by the bondholder - * @param _amount amount of bond tokens to remove from allowance - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. - */ - function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; - - /** - * @notice Lowers the allowance of several spenders by corresponding amount in `_amount` - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to remove from allowance - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease token allowance. - */ - function batchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount) external; - - /** - * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to remove from allowance - * @param _destinationChainID array of unique IDs that identifies the destination Chain. - * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. - */ - function batchCrossChainDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; + function decreaseAllowance(address _spender, uint256 _amount) external returns(bool); /** * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred @@ -190,42 +91,6 @@ interface IERC7092 { * @param _data additional information provided by the token holder */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). - * This methods also allows to attach data to the token that is being transferred - * @param _to the address to send the bonds to - * @param _amount amount of bond tokens to transfer - * @param _data additional information provided by the token holder - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint bond tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); - - /** - * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred - * @param _to array of addresses to send the bonds to - * @param _amount array of amount of bond tokens to transfer - * @param _data array of additional information provided by the token holder - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. - */ - function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). - * This methods also allows to attach data to the token that is being transferred - * @param _to array of addresses to send the bonds to - * @param _amount array of amounts of bond tokens to transfer - * @param _data array of additional information provided by the token holder - * @param _destinationChainID array of unique IDs that identify the destination Chains. - * @param _destinationContract array of smart contracts to interact with in the destination Chains in order to Deposit or Mint bond tokens that are transferred. - * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function batchCrossChainTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function @@ -236,46 +101,6 @@ interface IERC7092 { * @param _data additional information provided by the token holder */ function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) - * This methods also allows to attach data to the token that is being transferred - * @param _from the bondholder address - * @param _to the address to transfer bonds to - * @param _amount amount of bond tokens to transfer - * @param _data additional information provided by the token holder - * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); - - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function - * This methods also allows to attach data to the token that is being transferred - * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bond tokens to - * @param _amount array of amount of bond tokens to transfer. - * @param _data array of additional information provided by the token holder - * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. - */ - function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); - - /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) - * This methods also allows to attach data to the token that is being transferred - * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bonds to - * @param _amount array of amount of bond tokens to transfer - * @param _data array of additional information provided by the token holder - * @param _destinationChainID array of unique IDs that identifies the destination Chain. - * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. - * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. - */ - function batchCrossChainTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation @@ -286,96 +111,11 @@ interface IERC7092 { event Transfer(address _from, address _to, uint256 _amount); /** - * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain - * @param _from the account that owns bonds - * @param _to the account that receives the bond - * @param _amount amount of bond tokens to be transferred - * @param _destinationChainID The unique ID that identifies the destination Chain - */ - event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); - - /** - * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation - * @param _from bond token's owner - * @param _to array of accounts that receives the bond - * @param _amount array of amount of bond tokens to be transferred - */ - event TransferBatch(address _from, address[] _to, uint256[] _amount); - - /** - * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain - * @param _from the bond token's owner - * @param _to array of accounts that receive the bond - * @param _amount array of amount of bond tokens to be transferred - * @param _destinationChainID array of unique IDs that identify the destination Chain - */ - event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); - - /** - * @notice MUST be emitted when an account is approved + * @notice MUST be emitted when an account is approved or when the allowance is decreased * @param _owner bond token's owner * @param _spender the account to be allowed to spend bonds - * @param _amount amount of bond tokens allowed by _owner to be spent by _spender. + * @param _amount amount of bond tokens allowed by _owner to be spent by `_spender` + * Or amount of bond tokens to decrease allowance from `_spender` */ event Approval(address _owner, address _spender, uint256 _amount); - - /** - * @notice MUST be emitted when an account is approved cross-chain - * @param _owner the bonds owner - * @param _spender the account to be allowed to spend bonds - * @param _amount amount of bond tokens allowed by _owner to be spent by _spender - * @param _destinationChainID The unique ID that identifies the destination Chain - */ - event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); - - /** - * @notice MUST be emitted when a batch of accounts are approved - * @param _owner bond token's owner - * @param _spender array of accounts to be allowed to spend bonds - * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender. - */ - event ApprovalBatch(address _owner, address[] _spender, uint256[] _amount); - - /** - * @notice MUST be emitted when a batch of accounts are approved cross-chain - * @param _owner bond token's owner - * @param _spender array of accounts to be allowed to spend bonds - * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender - * @param _destinationChainID array of unique IDs that identify the destination Chain - */ - event CrossChainApprovalBatch(address _owner, address[] _spender, uint256[] _amount, uint64[] _destinationChainID); - - /** - * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` - * @param _owner the bonds owner - * @param _spender the account that has been allowed to spend bonds - * @param _amount amount of bond tokens to disapprove - */ - event DecreaseApproval(address _owner, address _spender, uint256 _amount); - - /** - * @notice MUST be emmitted when the `_owner` decreases allowance from `_sepnder` by quantity `_amount` cross-chain - * @param _owner the bonds owner - * @param _spender the account that has been allowed to spend bonds - * @param _amount amount of bond tokens to disapprove - * @param _destinationChainID The unique ID that identifies the destination Chain - */ - event CrossChainDecreaseApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); - - /** - * @notice MUST be emmitted when `_owner` decreases allowance from several sepnders by corresponding quantity in the array `_amount` - * @param _owner the bonds owner - * @param _spender array of accounts that had been allowed to spend bonds - * @param _amount array of amount of bond tokens to disapprove - */ - event DecreaseApprovalBatch(address _owner, address[] _spender, uint256[] _amount); - - /** - * @notice MUST be emmitted when the `_owner` decreases allowance from several sepnders by corresponding quantity in `_amount` cross-chain - * @param _owner the bonds owner - * @param _spender array of accounts that have been allowed to spend bonds - * @param _amount array of amount of bond tokens to disapprove - * @param _destinationChainID array of unique IDs that identify the destination Chain - */ - event CrossChainDecreaseApprovalBatch(address _owner, address _spender[], uint256 _amount[], uint64 _destinationChainID[]); } From f0b3be21af7803fb91f517f6f17c06c4bd87dbe2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:32:01 +0200 Subject: [PATCH 31/40] Update IERC7092 --- assets/eip-7092/IERC7092.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index 68641994e6c20..e51d623d2f66a 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.0; /** * @title ERC-7092 Financial Bonds tandard +* This interface implements only functions that are REQUIRED for the ERC7092 standard. +* OPTIONAL and INTEROPERABLE functions may be added to allow further functionalities and interoperability of bonds */ interface IERC7092 { /** From 460f77a3d18d76ee568cb20d554151e4cc51e610 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:37:50 +0200 Subject: [PATCH 32/40] Update CouponMath --- assets/eip-7092/coupons/CouponMath.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/eip-7092/coupons/CouponMath.sol b/assets/eip-7092/coupons/CouponMath.sol index 458b42d5d2c91..10b312ad3ab4b 100644 --- a/assets/eip-7092/coupons/CouponMath.sol +++ b/assets/eip-7092/coupons/CouponMath.sol @@ -14,10 +14,9 @@ library CouponMath { address _bondContract ) external view returns(uint256) { uint256 couponRate = IERC7092(_bondContract).couponRate(); - uint256 denomination = IERC7092(_bondContract).denomination(); uint256 principal = IERC7092(_bondContract).principalOf(_investor); - return principal * denomination * couponRate; + return principal * couponRate; } /** @@ -32,12 +31,11 @@ library CouponMath { address _bondContract ) external view returns(uint256) { uint256 couponRate = IERC7092(_bondContract).couponRate(); - uint256 denomination = IERC7092(_bondContract).denomination(); uint256 principal = IERC7092(_bondContract).principalOf(_investor); uint256 frequency = IERC7092(_bondContract).couponFrequency(); uint256 numberOfDays = _numberOfDays(_bondContract); - return principal * denomination * couponRate * _duration / (frequency * numberOfDays); + return principal * couponRate * _duration / (frequency * numberOfDays); } /** From 5b035bc6c74013e216a4307ae77db5042072df43 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sun, 8 Oct 2023 00:03:45 +0200 Subject: [PATCH 33/40] Update eip-7092 --- EIPS/eip-7092.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index e03caea674320..6114f4ba84a48 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -241,7 +241,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u function batchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount) external; /** - * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred + * @notice Moves several bonds with amounts in the array `_amount` to corresponding address in the array `_to`, with additional data attached * @param _to array of addresses to send the bonds to * @param _amount array of amount of bond tokens to transfer * @param _data array of additional information provided by the token holder @@ -251,7 +251,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * @notice Moves several bonds with amounts in the array `_amount` to corresponding address in the array `_to` from an account that have been authorized by `_from` addresses * This methods also allows to attach data to the token that is being transferred * @param _from array of bondholder addresses * @param _to array of addresses to transfer bond tokens to @@ -263,7 +263,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice MUST be emitted when a batch of bond tokens are transferred, issued or redeemed, except during contract creation + * @notice MUST be emitted when several bond tokens are transferred, issued or redeemed, except during contract creation * @param _from bond token's owner * @param _to array of accounts that receives the bond * @param _amount array of amount of bond tokens to be transferred @@ -273,7 +273,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u event TransferBatch(address _from, address[] _to, uint256[] _amount); /** - * @notice MUST be emitted when a batch of accounts are approved or when the allowance is removed from a batch of accounts + * @notice MUST be emitted when several accounts are approved or when the allowance is removed from several accounts * @param _owner bond token's owner * @param _spender array of accounts to be allowed to spend bonds * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender. @@ -330,7 +330,7 @@ The destination chain identifier should be the one specified by the cross-chain function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; /** - * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @notice Lowers the allowance of several spenders by amounts in the array `_amount` in the destination Chain * @param _spender array of addresses to be authorized by the bondholder * @param _amount array of amount of bond tokens to remove from allowance * @param _destinationChainID array of unique IDs that identifies the destination Chain. @@ -341,7 +341,7 @@ The destination chain identifier should be the one specified by the cross-chain function crossChainBatchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; /** - * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). * This methods also allows to attach data to the token that is being transferred * @param _to the address to send the bonds to * @param _amount amount of bond tokens to transfer @@ -354,7 +354,7 @@ The destination chain identifier should be the one specified by the cross-chain function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice Moves `_amount` bonds to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * @notice Moves several bond tokens with amounts in the array `_amount` to addresses in the array `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). * This methods also allows to attach data to the token that is being transferred * @param _to array of addresses to send the bonds to * @param _amount array of amounts of bond tokens to transfer @@ -367,7 +367,7 @@ The destination chain identifier should be the one specified by the cross-chain function crossChainBatchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * @notice Moves `_amount` bond tokens from the `_from`account to address `_to` from the current Chain to another Chain. The caller must be approved by `_from` address. * This methods also allows to attach data to the token that is being transferred * @param _from the bondholder address * @param _to the address to transfer bonds to @@ -381,7 +381,8 @@ The destination chain identifier should be the one specified by the cross-chain function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function, from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon) + * @notice Moves several bond tokens with amounts in the array `_amount` from addresses in the array `_from` to addresses in the array `_to` from the current Chain to another Chain. + * The caller must be approved by `_from` accounts to spend corresponding amounts in the array `_amount * This methods also allows to attach data to the token that is being transferred * @param _from array of bondholder addresses * @param _to array of addresses to transfer bonds to @@ -404,7 +405,7 @@ The destination chain identifier should be the one specified by the cross-chain event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); /** - * @notice MUST be emitted when a batch of bond tokens are transferred or redeemed cross-chain + * @notice MUST be emitted when several bond tokens are transferred or redeemed cross-chain * @param _from the bond token's owner * @param _to array of accounts that receive the bond * @param _amount array of amount of bond tokens to be transferred @@ -422,7 +423,7 @@ The destination chain identifier should be the one specified by the cross-chain event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); /** - * @notice MUST be emitted when a batch of accounts are approved cross-chain + * @notice MUST be emitted when a several accounts are approved or when the allowance of several accounts is reduced cross-chain * @param _owner bond token's owner * @param _spender array of accounts to be allowed to spend bonds * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender From b7a521297d898b46ee6f0bcfefdce5b735dbedaa Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sun, 8 Oct 2023 16:16:26 +0200 Subject: [PATCH 34/40] Update eip-7092 - Day count basis must return uint8 --- EIPS/eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 6114f4ba84a48..b14554be8ad4f 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -220,7 +220,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ - function dayCountBasis() external view returns(uint256); + function dayCountBasis() external view returns(uint8); /** * @notice Authorizes several spenders account to manage `_amount`of their bond tokens From 6576dfb8e16f5708d7925a523c67cb6d7940e270 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 9 Oct 2023 03:53:59 +0200 Subject: [PATCH 35/40] Update eip-7092 - add issuerAddress in Callable Bond example --- EIPS/eip-7092.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index b14554be8ad4f..89bd83b13e856 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -498,13 +498,16 @@ import 'ERC7092.sol'; contract ERC7092Callable is ERC7092 { // WRITE THE LOGIC TO ALLOW THE ISSUER TO CALL BONDS // STATE VARIABLES AND FUNCTIONS NEEDED + + address public issuerAddress; /** * @notice call bonds owned by `_investor` * MUST be called by the issuer only */ function call(address _investor) public { - require(_principals[_investor] > 0, "ERC7092Callable: ONLY_ISSUER"); + require(msg.sender === issuerAddress, "ERC7092Callable: ONLY_ISSUER"); + require(_principals[_investor] > 0, "ERC7092Callable: NO_BOND_FOUND"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Callable: BOND_MATURED"); uint256 principal = _principals[_investor]; @@ -531,7 +534,7 @@ contract ERC7092Puttable is ERC7092 { * MUST be called by investors who own bonds */ function put() public { - require(_principals[msg.sender] > 0, "ERC7092Puttable: ONLY_INVESTORS"); + require(_principals[msg.sender] > 0, "ERC7092Puttable: NO_BOND_FOUND"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Puttable: BOND_MATURED"); uint256 principal = _principals[msg.sender]; @@ -558,7 +561,7 @@ contract ERC7092Convertible is ERC7092 { * Issuer can also convert invetsors bonds to equity. */ function convert() public { - require(_principals[msg.sender] > 0, "ERC7092Convertible: ONLY_INVESTORS"); + require(_principals[msg.sender] > 0, "ERC7092Convertible: NO_BOND_FOUND"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Convertible: BOND_MATURED"); uint256 principal = _principals[msg.sender]; From eb3e30652dc3d51b1bd5f0f61c99a6bb385ea66d Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 11 Oct 2023 18:46:07 +0200 Subject: [PATCH 36/40] Update eip-7092 - correct typos --- EIPS/eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 89bd83b13e856..0dc13b8a755a7 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -104,7 +104,7 @@ interface IERC7092 { function issueDate() external view returns(uint256); /** - * @notice Returns the bond maturity date, i.e, the date when the pricipal is repaid. This is a Unix Timestamp like the one returned by block.timestamp + * @notice Returns the bond maturity date, i.e, the date when the principal is repaid. This is a Unix Timestamp like the one returned by block.timestamp * The maturity date MUST be greater than the issue date */ function maturityDate() external view returns(uint256); From 39da8a26112512feedaedb6b1f6b43848cbb0e74 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 19 Oct 2023 03:10:57 +0200 Subject: [PATCH 37/40] Correct grammatical errors as suggested by @Pandapip1 --- EIPS/eip-7092.md | 221 ++++++++++++++++++++++------------------------- 1 file changed, 105 insertions(+), 116 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 0dc13b8a755a7..af5a98e01fc0c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -15,34 +15,26 @@ created: 2023-05-28 This proposal introduces fixed income financial bonds. Important bond characteristics such as the International Securities Identification Number (ISIN), the issue volume, the issue date, the maturity date, the coupon rate, the coupon frequency, the principal, or the day count basis are defined to allow issuing bonds in the primary market (origination), and different transfer functions allow to buy or sell bonds in the secondary market. The standard also provides a -functionality to allow bonds to be approved by owners in order to be spent by third party, and cross-chain functionalities that allow bond tokens of an issue to be +functionality to allow bonds to be approved by owners in order to be spent by third party, and cross-chain functionalities that allow bond tokens to be managed accross several blockchains. ## Motivation -Fixed income instruments is one of the asset classes that is widely used by corporations and other entities to raise funds. Bonds -are considered more secured than equity since the issuer is supposed to repay the principal at maturity in addition to coupons -that are paid to investsors. +Fixed income instruments are one of the asset classes widely used by corporations and other entities to raise funds. Bonds are considered more secure than equity because the issuer is obligated to repay the principal at maturity, in addition to the coupons paid to investors. -This standard interface allows fixed income instruments to be represented as on-chain tokens, so as they can be managed through wallets, -and used by applications like decentrailized exchanges, digital platforms for investment banks, etc... +This standard interface allows fixed income instruments to be represented as on-chain tokens, making it possible for them to be managed through wallets and utilized by applications, such as decentralized exchanges and digital platforms for investment banks. -The existing standard [ERC-3475](./eip-3475) that may be used to create abstract storage bonds does not follow same standards as -with traditional bonds. By introducing concepts such as **classes** and **nonces** that are not used for traditional bonds, the ERC-3475 standard makes it difficult for -traditional entities to migrate to tokenized bonds. Morever, the use of on-chain metadata with ERC-3475, like **classMetadata** and **nonceMetadata**, and also **classValues** -leads to unnecessary gas consumption. The lack of named variables like coupon, maturity date, principal, etc... makes it difficult to implement the ERC-3475 since developers -need to rember which metadata is assigned to each parameter. +The existing standard, [ERC-3475](./eip-3475), which is used to create abstract storage bonds, deviates from traditional bond standards. It introduces concepts such as classes and nonces, which are not commonly used in traditional bonds, making it challenging for traditional entities to transition to tokenized bonds. Moreover, the use of on-chain metadata, such as classMetadata, nonceMetadata, and classValues in ERC-3475, results in unnecessary gas consumption. The absence of named variables like coupon, maturity date, principal, etc., complicates the implementation of ERC-3475, as developers must remember which metadata is associated with each parameter. -By keeping same standards as with traditional bonds, the [ERC-7092](./eip-7092.md) allows to create a new token for bonds with same caracteristics as traditional bonds so as to make it simple -to migrate to tokenized bonds. +By adhering to the same standards as traditional bonds, [ERC-7092](./eip-7092.md) enables the creation of new tokens for bonds with identical characteristics to traditional bonds, simplifying the migration to tokenized bonds. -Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: +Tokenizing bonds offers several advantages compared to traditional bond issuance and trading, including: -1. Fractional ownership: The bond standard does not limit the bond denomination to some minimum value compared to traditioanal bonds where the denomination is typically equal to $100 or $1,000. -2. Accessibility: By allowing lower investment thresholds, tokenized bonds are supposed to attract retail investors who could not participate in traditional markets due to high minimum investment requirements. -3. Increased liquidity: Fractioanal ownership will bring new investors in the bond market, this will increase liquidity in the bond market. -4. Cost savings: By replacing intermediaries with smart contracts, bond's tokenization will reduce costs associated with the bond issuance and management. -5. Easy accessibility and 24/7 trading: Tokenized bonds are supposed to be traded on digital platforms such as decentralized exchanges. Therefore, they will be more accessible compared to tradional bond market. +1. Fractional Ownership: Token standards do not impose a minimum denomination requirement, unlike traditional bonds, which typically have denominations of $100 or $1,000. +2. Accessibility: By allowing lower investment thresholds, tokenized bonds aim to attract retail investors who were previously unable to participate in traditional markets due to high minimum investment requirements. +3. Increased Liquidity: Fractional ownership will introduce new investors to the bond market, increasing liquidity. +4. Cost Savings: By replacing intermediaries with smart contracts, bond tokenization reduces costs associated with bond issuance and management. +5. Easy Accessibility and 24/7 Trading: Tokenized bonds are expected to be traded on digital platforms, including decentralized exchanges, making them more accessible compared to traditional bond markets. ## Specification @@ -70,83 +62,82 @@ interface IERC7092 { /** * @notice Returns the bond symbol - * It is RECOMMENDED to represent the symbol as a combination of the issuer Issuer'shorter name and the maturity date + * It is RECOMMENDED to represent the symbol as a combination of the issuer issuer's shorter name and the maturity date * Ex: If a company named Green Energy issues bonds that will mature on october 25, 2030, the bond symbol could be `GE30` or `GE2030` or `GE102530` */ function symbol() external view returns(string memory); /** - * @notice Returns the bond currency. This is the contract address of the token used to pay and return the bond principal + * @notice Returns the bond currency. This is the contract address of the token used to make payments and return the bond principal */ function currency() external view returns(address); /** - * @notice Returns the bond denominiation. This is the minimum amount in which the Bonds may be issued. It must be expressend in unit of the principal currency - * ex: If the denomination is equal to 1,000 and the currency is USDC, then the bond denomination is equal to 1,000 USDC + * @notice Returns the bond denomination. This is the minimum amount in which the bonds may be issued. It MUST be expressed in units of the principal currency. + * ex: If the denomination is set at 1,000, and the currency is USDC, then the bond denomination is equivalent to 1,000 USDC. */ function denomination() external view returns(uint256); /** - * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in denomination unit. + * @notice Returns the issue volume, which represents the total debt amount. It is RECOMMENDED to express the issue volume in terms of the denomination unit. */ function issueVolume() external view returns(uint256); /** - * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis point unit. + * @notice Returns the bond interest rate. It is RECOMMENDED to express the interest rate in basis points (bps). * 1 basis point = 0.01% = 0.0001 * ex: if interest rate = 5%, then coupon() => 500 basis points */ function couponRate() external view returns(uint256); /** - * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp like the one returned by block.timestamp + * @notice Returns the date when bonds were issued to investors. This is a Unix Timestamp similar the one returned by block.timestamp */ function issueDate() external view returns(uint256); /** - * @notice Returns the bond maturity date, i.e, the date when the principal is repaid. This is a Unix Timestamp like the one returned by block.timestamp + * @notice Returns the bond maturity date, i.e, the date when the principal is repaid. This is a Unix Timestamp similar the one returned by block.timestamp * The maturity date MUST be greater than the issue date */ function maturityDate() external view returns(uint256); /** - * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (USDC, DAI, etc...) + * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in the bond currency unit (e.g., USDC, DAI, etc) * @param _account account address */ function principalOf(address _account) external view returns(uint256); /** - * @notice Returns the amount of tokens the `_spender` account has been authorized by the `_owner`` - * acount to manage their bonds + * @notice Returns the number of tokens that the `_spender` account has been authorized by the `_owner` to manage * @param _owner the bondholder address * @param _spender the address that has been authorized by the bondholder */ function allowance(address _owner, address _spender) external view returns(uint256); /** - * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens - * @param _spender the address to be authorized by the bondholder + * @notice Authorizes `_spender` account to manage a specified `_amount`of the bondholder's tokens + * @param _spender the account to be authorized by the bondholder * @param _amount amount of bond tokens to approve */ function approve(address _spender, uint256 _amount) external returns(bool); /** - * @notice Lowers the allowance of `_spender` by `_amount` + * @notice Decreases the allowance granted to `_spender` by `_amount` * @param _spender the address to be authorized by the bondholder * @param _amount amount of bond tokens to remove from allowance */ function decreaseAllowance(address _spender, uint256 _amount) external; /** - * @notice Moves `_amount` bonds to address `_to`. This methods also allows to attach data to the token that is being transferred - * @param _to the address to send the bonds to + * @notice Transfers `_amount` bonds to the address `_to`. Additionally, this method enables to attach data to the token being transferred + * @param _to the address to send bonds to * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder */ function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** - * @notice Moves `_amount` bonds from an account that has authorized the caller through the approve function + * @notice Transfers `_amount` bonds from an account that has previously authorized the caller through the `approve` function * This methods also allows to attach data to the token that is being transferred * @param _from the bondholder address * @param _to the address to transfer bonds to @@ -156,16 +147,16 @@ interface IERC7092 { function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** - * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, except during contract creation - * @param _from the account that owns bonds - * @param _to the account that receives the bond + * @notice MUST be emitted when bond tokens are transferred, issued or redeemed, with the exception being during contract creation + * @param _from bondholder account + * @param _to account to transfer bonds to * @param _amount amount of bond tokens to be transferred */ event Transfer(address _from, address _to, uint256 _amount); /** - * @notice MUST be emitted when an account is approved or when the allowance is decreased - * @param _owner bond token's owner + * @notice MUST be emitted when an account is approved to spend tokens or when the allowance is decreased + * @param _owner bondholder account * @param _spender the account to be allowed to spend bonds * @param _amount amount of bond tokens allowed by _owner to be spent by `_spender` * Or amount of bond tokens to decrease allowance from `_spender` @@ -182,18 +173,18 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u - The `couponType` MAY be employed to signify the interest rate that the issuer has committed to paying to investors, which may take various forms such as zero coupon, fixed rate, floating rate, and more. - The `couponFrequency` refers to how often the bond pays interest to its bondholders, and is typically expressed in terms of time periods, such as: Annual, Semi-Annual, Quarterly, or Monthly. - The `dayCountBasis` is used to calculate the accrued interest on a bond between two coupon payment dates or other specific periods. Some of the day count basis are: Actual/Actual, 30/360, Actual/360, Actual/365, or 30/365 -- Batch functions such as `batchApprove`, `batchTransfer` and more are used to optimize and streamline multiple operations into a single function call. This provide atomicity and gas usage optimization. +- Batch functions like `batchApprove`, `batchTransfer`, and others are used to optimize and consolidate multiple operations into a single function call. This provides atomicity and optimizes gas usage ```solidity /** - * @notice Returns the number of decimals the bond uses - e.g `10`, means to divide the token amount by `10000000000` + * @notice Returns the number of decimals used by the bond. For example, if it returns `10`, it means that the token amount MUST be multiplied by 10000000000 to get the standard representation. * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function decimals() external view returns(uint8); /** - * @notice Returns the copoun currency. This is the contract address of the token used to pay coupons. It can be same as the the one used for the principal + * @notice Rreturns the coupon currency, which is represented by the contract address of the token used to pay coupons. It can be the same as the one used for the principal * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ @@ -201,7 +192,7 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u /** * @notice Returns the coupon type - * An example could be => 0: Zero coupon, 1: Fixed Rate, 2: Floating Rate, etc... + * For example, 0 can denote Zero coupon, 1 can denote Fixed Rate, 2 can denote Floating Rate, and so on * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ @@ -216,34 +207,34 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u /** * @notice Returns the day count basis - * An example could be => 0: actual/actual, 1: actual/360, etc... + * For example, 0 can denote actual/actual, 1 can denote actual/360, and so on * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function dayCountBasis() external view returns(uint8); /** - * @notice Authorizes several spenders account to manage `_amount`of their bond tokens - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to approve + * @notice Authorizes multiple spender accounts to manage a specified `_amount` of the bondholder tokens + * @param _spender array of accounts to be authorized by the bondholder + * @param _amount array of amounts of bond tokens to approve * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function batchApprove(address[] calldata _spender, uint256[] calldata _amount) external returns(bool); /** - * @notice Lowers the allowance of several spenders by corresponding amount in `_amount` - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to remove from allowance + * @notice Decreases the allowance of multiple spenders by corresponding amounts in `_amount` + * @param _spender array of accounts to be authorized by the bondholder + * @param _amount array of amounts of bond tokens to decrease the allowance from * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease token allowance. */ function batchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount) external; /** - * @notice Moves several bonds with amounts in the array `_amount` to corresponding address in the array `_to`, with additional data attached - * @param _to array of addresses to send the bonds to - * @param _amount array of amount of bond tokens to transfer + * @notice Transfers multiple bonds with amounts specified in the array `_amount` to the corresponding accounts in the array `_to`, with the option to attach additional data + * @param _to array of accounts to send the bonds to + * @param _amount array of amounts of bond tokens to transfer * @param _data array of additional information provided by the token holder * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. @@ -251,11 +242,11 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u function batchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice Moves several bonds with amounts in the array `_amount` to corresponding address in the array `_to` from an account that have been authorized by `_from` addresses - * This methods also allows to attach data to the token that is being transferred - * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bond tokens to - * @param _amount array of amount of bond tokens to transfer. + * @notice Transfers multiple bonds with amounts specified in the array `_amount` to the corresponding accounts in the array `_to` from an account that have been authorized by the `_from` account + * This method also allows to attach data to tokens that are being transferred + * @param _from array of bondholder accounts + * @param _to array of accounts to transfer bond tokens to + * @param _amount array of amounts of bond tokens to transfer. * @param _data array of additional information provided by the token holder * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. @@ -263,20 +254,20 @@ The following functions are OPTIONAL. They MAY be used to improve the standard u function batchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data) external returns(bool); /** - * @notice MUST be emitted when several bond tokens are transferred, issued or redeemed, except during contract creation - * @param _from bond token's owner - * @param _to array of accounts that receives the bond - * @param _amount array of amount of bond tokens to be transferred + * @notice MUST be emitted when multiple bond tokens are transferred, issued or redeemed, with the exception being during contract creation + * @param _from bondholder account + * @param _to array of accounts to transfer bonds to + * @param _amount array of amounts of bond tokens to be transferred * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchTransfer` and `batchTransferFrom` functions */ event TransferBatch(address _from, address[] _to, uint256[] _amount); /** - * @notice MUST be emitted when several accounts are approved or when the allowance is removed from several accounts - * @param _owner bond token's owner - * @param _spender array of accounts to be allowed to spend bonds - * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender. + * @notice MUST be emitted when multiple accounts are approved or when the allowance is decreased from multiple accounts + * @param _owner bondholder account + * @param _spender array of accounts to be allowed to spend bonds, or to decrase the allowance from + * @param _amount array of amounts of bond tokens allowed by `_owner` to be spent by multiple accounts in `_spender`. * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. MUST be emitted in `batchApprove` and `batchDecreaseAllowance` functions */ @@ -297,115 +288,115 @@ The destination chain identifier should be the one specified by the cross-chain ```solidity /** - * @notice Authorizes `_spender` account to manage `_amount`of their bond tokens in the destination Chain - * @param _spender the address to be authorized by the bondholder + * @notice Authorizes the `_spender` account to manage a specified `_amount`of the bondholder bond tokens on the destination Chain + * @param _spender account to be authorized by the bondholder * @param _amount amount of bond tokens to approve * @param _destinationChainID The unique ID that identifies the destination Chain. - * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. + * @param _destinationContract The smart contract to interact with in the destination Chain * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens in a different chain than the current chain */ function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice Authorizes several spender accounts to manage `_amount`of their bond tokens in the destination Chain - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to approve + * @notice Authorizes multiple spender accounts in `_spender` to manage specified amounts in `_amount` of the bondholder tokens on the destination chain + * @param _spender array of accounts to be authorized by the bondholder + * @param _amount array of amounts of bond tokens to approve * @param _destinationChainID array of unique IDs that identifies the destination Chain. * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function crossChainBatchApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** - * @notice Lowers the allowance of `_spender` by `_amount` in the destination Chain + * @notice Decreases the allowance of `_spender` by a specified `_amount` on the destination Chain * @param _spender the address to be authorized by the bondholder * @param _amount amount of bond tokens to remove from allowance * @param _destinationChainID The unique ID that identifies the destination Chain. * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; /** - * @notice Lowers the allowance of several spenders by amounts in the array `_amount` in the destination Chain - * @param _spender array of addresses to be authorized by the bondholder - * @param _amount array of amount of bond tokens to remove from allowance + the array * @notice Decreases the allowance of multiple spenders in `_spender` by corresponding amounts specified in the array `_amount` on the destination chain + * @param _spender array of accounts to be authorized by the bondholder + * @param _amount array of amounts of bond tokens to decrease the allowance from * @param _destinationChainID array of unique IDs that identifies the destination Chain. * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to decrease the token allowance cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function crossChainBatchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; /** - * @notice Moves `_amount` bond tokens to address `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * @notice Moves `_amount` bond tokens to the address `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon). * This methods also allows to attach data to the token that is being transferred - * @param _to the address to send the bonds to + * @param _to account to send bond tokens to * @param _amount amount of bond tokens to transfer - * @param _data additional information provided by the token holder + * @param _data additional information provided by the bondholder * @param _destinationChainID The unique ID that identifies the destination Chain. * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint bond tokens that are transferred. * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice Moves several bond tokens with amounts in the array `_amount` to addresses in the array `_to` from the current Chain to another Chain (Ex: move tokens from Ethereum to Polygon). + * @notice Transfers multiple bond tokens with amounts specified in the array `_amount` to the corresponding accounts in the array `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon). * This methods also allows to attach data to the token that is being transferred - * @param _to array of addresses to send the bonds to + * @param _to array of accounts to send the bonds to * @param _amount array of amounts of bond tokens to transfer - * @param _data array of additional information provided by the token holder + * @param _data array of additional information provided by the bondholder * @param _destinationChainID array of unique IDs that identify the destination Chains. * @param _destinationContract array of smart contracts to interact with in the destination Chains in order to Deposit or Mint bond tokens that are transferred. * - * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ function crossChainBatchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** - * @notice Moves `_amount` bond tokens from the `_from`account to address `_to` from the current Chain to another Chain. The caller must be approved by `_from` address. + * @notice Transfers `_amount` bond tokens from the `_from`account to the `_to` account from the current chain to another chain. The caller must be approved by the `_from` address. * This methods also allows to attach data to the token that is being transferred * @param _from the bondholder address - * @param _to the address to transfer bonds to + * @param _to the account to transfer bonds to * @param _amount amount of bond tokens to transfer * @param _data additional information provided by the token holder * @param _destinationChainID The unique ID that identifies the destination Chain. * @param _destinationContract The smart contract to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present */ function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); /** - * @notice Moves several bond tokens with amounts in the array `_amount` from addresses in the array `_from` to addresses in the array `_to` from the current Chain to another Chain. - * The caller must be approved by `_from` accounts to spend corresponding amounts in the array `_amount + * @notice Transfers several bond tokens with amounts specified in the array `_amount` from accounts in the array `_from` to accounts in the array `_to` from the current chain to another chain. + * The caller must be approved by the `_from` accounts to spend the corresponding amounts specified in the array `_amount` * This methods also allows to attach data to the token that is being transferred * @param _from array of bondholder addresses - * @param _to array of addresses to transfer bonds to - * @param _amount array of amount of bond tokens to transfer + * @param _to array of accounts to transfer bonds to + * @param _amount array of amounts of bond tokens to transfer * @param _data array of additional information provided by the token holder * @param _destinationChainID array of unique IDs that identifies the destination Chain. * @param _destinationContract array of smart contracts to interact with in the destination Chain in order to Deposit or Mint tokens that are transferred. * - ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to transfer tokens cross-chain. + ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present */ function crossChainBatchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** - * @notice MUST be emitted when bond tokens are transferred or redeemed cross-chain - * @param _from the account that owns bonds - * @param _to the account that receives the bond + * @notice MUST be emitted when bond tokens are transferred or redeemed in a cross-chain transaction + * @param _from bondholder account + * @param _to account the transfer bond tokens to * @param _amount amount of bond tokens to be transferred * @param _destinationChainID The unique ID that identifies the destination Chain */ event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); /** - * @notice MUST be emitted when several bond tokens are transferred or redeemed cross-chain + * @notice MUST be emitted when several bond tokens are transferred or redeemed in a cross-chain transaction * @param _from the bond token's owner * @param _to array of accounts that receive the bond * @param _amount array of amount of bond tokens to be transferred @@ -414,16 +405,16 @@ The destination chain identifier should be the one specified by the cross-chain event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); /** - * @notice MUST be emitted when an account is approved cross-chain - * @param _owner the bonds owner + * @notice MUST be emitted when an account is approved to spend the bondholder's tokens in a different chain than the current chain + * @param _owner the bondholder account * @param _spender the account to be allowed to spend bonds - * @param _amount amount of bond tokens allowed by _owner to be spent by _spender + * @param _amount amount of bond tokens allowed by `_owner` to be spent by `_spender` * @param _destinationChainID The unique ID that identifies the destination Chain */ event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); /** - * @notice MUST be emitted when a several accounts are approved or when the allowance of several accounts is reduced cross-chain + * @notice MUST be emitted when multiple accounts in the array `_spender` are approved or when the allowances of multiple accounts in the array `_spender` are reduced on the destination chain which MUST be different than the current chain * @param _owner bond token's owner * @param _spender array of accounts to be allowed to spend bonds * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender @@ -434,7 +425,7 @@ The destination chain identifier should be the one specified by the cross-chain ## Rationale -The financial bond standard is specifically designed to represent fixed income assets, which essentially signify a loan provided by an investor to a borrower. The motivation behind this design stems from the need to tokenize fixed income assets and present the bond tokens with characteristics mirroring those found in traditional finance. Maintaining these familiar properties is essential for both issuers and investors, as it eases the transition to tokenized bonds without significant hurdles. +The financial bond standard is specifically designed to represent fixed income assets, which essentially represent a loan provided by an investor to a borrower. The motivation behind this design stems from the need to tokenize fixed income assets and present the bond tokens with characteristics mirroring those found in traditional finance. Maintaining these familiar properties is essential for both issuers and investors, as it eases the transition to tokenized bonds without significant hurdles. The conventional finance structure, involving an issuer, an investment bank, and investors, can be seamlessly translated into the bond standard. In this context, smart contracts have the potential to replace the role of the investment bank intermediary. In cases of institutional issuance, the management of these smart contracts may be overseen by the investment bank. Additionally, decentralized exchanges can leverage the bond standard to list bonds, with the responsibility of managing the associated smart contracts falling on these decentralized exchange platforms. @@ -442,7 +433,7 @@ Furthermore, various other entities can utilize this financial bond interface to The choice of terminology, such as `issueVolume` and `principalOf` instead of `totalSupply` and `balanceOf` as found in other standards like [ERC-20](./eip-20), is deliberate and stems from the aim of aligning with the terminology commonly used in traditional bonds. This approach ensures consistency with traditional financial terminology, making it easier for users to relate to and understand the tokenized bonds. -Moreover, the inclusion of a data input parameter in all transfer functions, which enables the transfer of additional data make the ERC-7092 not fully compatible with the ERC-20 standard. +Moreover, the inclusion of a data input parameter in all transfer functions, which enables the transfer of additional data, makes the ERC-7092 not fully compatible with the ERC-20 standard. Another important motivation for not extending other standards like ERC-20 with ERC-7092 is to enable token explorer platforms like Etherscan to represent ERC-7092 tokens as distinct entities with unique characteristics. By doing so, these platforms can provide additional information beyond just token balances. This added information might include essential bond characteristics such as the `interest rate` or `coupon rate`, as well as the `maturity date`. @@ -450,7 +441,7 @@ The inclusion of these bond-specific details in token representations is highly ### Total Supply -The decision not to explicitly define the `totalSupply` function in the ERC-7092 standard while providing a recommendation to implement it is a thoughtful approach. This choice acknowledges that the total supply of tokens in ERC-7092 can be derived from the `issueVolume` and the `denomination`, and it offers flexibility to developers. +The decision not to explicitly define the `totalSupply` function in the ERC-7092 standard while providing a recommendation to implement it is a thoughtful approach. This choice acknowledges that the total supply of tokens in ERC-7092 can be derived from the `issueVolume` and the `denomination`, offering flexibility to developers. While the standard doesn't mandate the inclusion of the `totalSupply` function, it strongly recommends its implementation. When developers choose to include it, they should ensure that the total supply accurately represents the ratio of the issueVolume and the denomination. @@ -468,13 +459,11 @@ The ERC-7092 does not to explicitly define the balanceOf function, as the token ## Backwards Compatibility -The ERC-7092 standard consciously deliberately avoids extending existing standards such as [ERC-20](./eip-20) or [ERC-1155](./eip-1155). This decision is motivated by the fact that some fundamental functions like `totalSupply` or `balanceOf` are not explicitly implemented in ERC-7092. +The ERC-7092 standard deliberately avoids extending existing standards, such as [ERC-20](./eip-20) or [ERC-1155](./eip-1155). This decision is motivated by the fact that some fundamental functions, like `totalSupply` or `balanceOf` are not explicitly implemented in ERC-7092. Instead, the ERC-7092 standard is designed to stand on its own as a distinct representation of a new token specifically tailored for bonds. It encompasses all the essential bond characteristics and functionalities directly within its structure. -**_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution -with other standards mentionned above SHOULD deviate from the standard. - +**_For the reasons mentioned above, we recommend a pure implementation of the standard_** for issuing tokenized bonds, as any hybrid solution involving the other standards mentioned SHOULD deviate from this standard. ## Reference Implementation @@ -482,9 +471,9 @@ The reference implementation of the [ERC-7092](./eip-7092.md) can be found [here Certain bonds come with embedded options that enhance their flexibility and offer unique features. As an illustration: -1.Callable bonds: These bonds grant the issuer the right, but not the obligation, to redeem or retire the bonds before their scheduled maturity date. This embedded call option provides issuers with the flexibility to reduce their debt obligations or take advantage of lower interest rates in the market by calling in and retiring the bonds when it becomes financially advantageous to do so. -2. Puttable bonds: These bonds provide investors with the right, but not the obligation, to sell the bonds back to the issuer or another specified entity before their scheduled maturity date. This embedded put option offers investors a degree of protection, allowing them to potentially receive their principal back before the maturity date if certain conditions are met. -3. Convertible bonds: They are a type of bond that comes with an embedded option, giving investors the right to convert their bonds into a specified number of common shares or equity securities of the issuer. This feature provides investors with the opportunity to participate in the potential future growth of the company issuing the bonds. +- Callable bonds: These bonds grant the issuer the right, but not the obligation, to redeem or retire the bonds before their scheduled maturity date. This embedded call option provides issuers with the flexibility to reduce their debt obligations or take advantage of lower interest rates in the market by calling in and retiring the bonds when it becomes financially advantageous to do so. +- Puttable bonds: These bonds provide investors with the right, but not the obligation, to sell the bonds back to the issuer or another specified entity before their scheduled maturity date. This embedded put option offers investors a degree of protection, allowing them to potentially receive their principal back before the maturity date if certain conditions are met. +- Convertible bonds: They are a type of bond that comes with an embedded option, giving investors the right to convert their bonds into a specified number of common shares or equity securities of the issuer. This feature provides investors with the opportunity to participate in the potential future growth of the company issuing the bonds. Bonds featuring embedded options can be generated by inheriting from the foundational ERC-7092 standard, which incorporates the ERC-7092 interface. This inheritance approach allows developers to build upon the base functionality of ERC-7092 while incorporating the specific features and logic required for bonds with embedded options. By extending the standard in this manner, developers can create specialized tokenized bond contracts that include the desired embedded option features, such as call options or put options. From 85bf3851a441b07c8abad818fed30f8a9db4405b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 19 Oct 2023 16:37:40 +0200 Subject: [PATCH 38/40] grammatical improvement --- EIPS/eip-7092.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index af5a98e01fc0c..f9fc5e97b26f2 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -12,11 +12,7 @@ created: 2023-05-28 ## Abstract -This proposal introduces fixed income financial bonds. Important bond characteristics such as the International Securities Identification Number (ISIN), -the issue volume, the issue date, the maturity date, the coupon rate, the coupon frequency, the principal, or the day count basis are defined to allow issuing -bonds in the primary market (origination), and different transfer functions allow to buy or sell bonds in the secondary market. The standard also provides a -functionality to allow bonds to be approved by owners in order to be spent by third party, and cross-chain functionalities that allow bond tokens to be -managed accross several blockchains. +This proposal introduces fixed income financial bonds. Important bond characteristics such as the International Securities Identification Number (ISIN), the issue volume, the issue date, the maturity date, the coupon rate, the coupon frequency, the principal, and the day count basis are defined to allow issuing bonds in the primary market (origination), and different transfer functions allow the buying or selling of bonds in the secondary market. The standard also provides functionality to allow bonds to be approved by owners in order to be spent by a third party, and cross-chain functionalities that allow bond tokens of an issue to be managed across several blockchains. ## Motivation From 5ff5d0a435ba492f94a5c7ed1930806809969012 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sun, 22 Oct 2023 19:51:15 +0200 Subject: [PATCH 39/40] Update eip-7092 - bytes32 as destinationChainID --- EIPS/eip-7092.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index f9fc5e97b26f2..826f9be22f2ca 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -292,7 +292,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. The method is used to approve tokens in a different chain than the current chain */ - function crossChainApprove(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external returns(bool); + function crossChainApprove(address _spender, uint256 _amount, bytes32 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Authorizes multiple spender accounts in `_spender` to manage specified amounts in `_amount` of the bondholder tokens on the destination chain @@ -303,7 +303,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function crossChainBatchApprove(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchApprove(address[] calldata _spender, uint256[] calldata _amount, bytes32[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice Decreases the allowance of `_spender` by a specified `_amount` on the destination Chain @@ -314,7 +314,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function crossChainDecreaseAllowance(address _spender, uint256 _amount, uint64 _destinationChainID, address _destinationContract) external; + function crossChainDecreaseAllowance(address _spender, uint256 _amount, bytes32 _destinationChainID, address _destinationContract) external; /** the array * @notice Decreases the allowance of multiple spenders in `_spender` by corresponding amounts specified in the array `_amount` on the destination chain @@ -325,7 +325,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function crossChainBatchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external; + function crossChainBatchDecreaseAllowance(address[] calldata _spender, uint256[] calldata _amount, bytes32[] calldata _destinationChainID, address[] calldata _destinationContract) external; /** * @notice Moves `_amount` bond tokens to the address `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon). @@ -338,7 +338,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + function crossChainTransfer(address _to, uint256 _amount, bytes calldata _data, bytes32 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Transfers multiple bond tokens with amounts specified in the array `_amount` to the corresponding accounts in the array `_to` from the current chain to another chain (e.g., moving tokens from Ethereum to Polygon). @@ -351,7 +351,7 @@ The destination chain identifier should be the one specified by the cross-chain * * OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present. */ - function crossChainBatchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchTransfer(address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, bytes32[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice Transfers `_amount` bond tokens from the `_from`account to the `_to` account from the current chain to another chain. The caller must be approved by the `_from` address. @@ -365,7 +365,7 @@ The destination chain identifier should be the one specified by the cross-chain * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present */ - function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, uint64 _destinationChainID, address _destinationContract) external returns(bool); + function crossChainTransferFrom(address _from, address _to, uint256 _amount, bytes calldata _data, bytes32 _destinationChainID, address _destinationContract) external returns(bool); /** * @notice Transfers several bond tokens with amounts specified in the array `_amount` from accounts in the array `_from` to accounts in the array `_to` from the current chain to another chain. @@ -380,7 +380,7 @@ The destination chain identifier should be the one specified by the cross-chain * ** OPTIONAL - interfaces and other contracts MUST NOT expect this function to be present */ - function crossChainBatchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, uint64[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); + function crossChainBatchTransferFrom(address[] calldata _from, address[] calldata _to, uint256[] calldata _amount, bytes[] calldata _data, bytes32[] calldata _destinationChainID, address[] calldata _destinationContract) external returns(bool); /** * @notice MUST be emitted when bond tokens are transferred or redeemed in a cross-chain transaction @@ -389,7 +389,7 @@ The destination chain identifier should be the one specified by the cross-chain * @param _amount amount of bond tokens to be transferred * @param _destinationChainID The unique ID that identifies the destination Chain */ - event CrossChainTransfer(address _from, address _to, uint256 _amount, uint64 _destinationChainID); + event CrossChainTransfer(address _from, address _to, uint256 _amount, bytes32 _destinationChainID); /** * @notice MUST be emitted when several bond tokens are transferred or redeemed in a cross-chain transaction @@ -398,7 +398,7 @@ The destination chain identifier should be the one specified by the cross-chain * @param _amount array of amount of bond tokens to be transferred * @param _destinationChainID array of unique IDs that identify the destination Chain */ - event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, uint64[] _destinationChainID); + event CrossChainTransferBatch(address _from, address[] _to, uint256[] _amount, bytes32[] _destinationChainID); /** * @notice MUST be emitted when an account is approved to spend the bondholder's tokens in a different chain than the current chain @@ -407,7 +407,7 @@ The destination chain identifier should be the one specified by the cross-chain * @param _amount amount of bond tokens allowed by `_owner` to be spent by `_spender` * @param _destinationChainID The unique ID that identifies the destination Chain */ - event CrossChainApproval(address _owner, address _spender, uint256 _amount, uint64 _destinationChainID); + event CrossChainApproval(address _owner, address _spender, uint256 _amount, bytes32 _destinationChainID); /** * @notice MUST be emitted when multiple accounts in the array `_spender` are approved or when the allowances of multiple accounts in the array `_spender` are reduced on the destination chain which MUST be different than the current chain @@ -416,7 +416,7 @@ The destination chain identifier should be the one specified by the cross-chain * @param _amount array of amount of bond tokens allowed by _owner to be spent by _spender * @param _destinationChainID array of unique IDs that identify the destination Chain */ - event CrossChainApprovalBatch(address _owner, address[] _spender, uint256[] _amount, uint64[] _destinationChainID); + event CrossChainApprovalBatch(address _owner, address[] _spender, uint256[] _amount, bytes32[] _destinationChainID); ``` ## Rationale From 99eeca1355826a9f74c4d6c616555c16ef27a6e3 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 25 Oct 2023 23:21:48 +0200 Subject: [PATCH 40/40] Update eip-7092 - typos --- EIPS/eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 826f9be22f2ca..dad09df322acb 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -43,7 +43,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S pragma solidity ^0.8.0; /** -* @title ERC-7092 Financial Bonds tandard +* @title ERC-7092 Financial Bonds Standard */ interface IERC7092 { /**