From 88225395fa8cffa10dcd446d34e1ebadd7d8afad Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sun, 28 May 2023 21:37:24 +0200 Subject: [PATCH 01/89] Add financial bonds draft --- eip-financial_bonds.md | 250 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 eip-financial_bonds.md diff --git a/eip-financial_bonds.md b/eip-financial_bonds.md new file mode 100644 index 0000000000000..d39ee30928793 --- /dev/null +++ b/eip-financial_bonds.md @@ -0,0 +1,250 @@ +--- +title: Financial Bonds +description: +author: Samuel Gwlanold Edoumou (@Edoumou) +discussions-to: https://ethereum-magicians.org/t/financial-bonds/14461 +status: Draft +type: Standards Track +category: ERC +created: 2023-05-28 +--- + +## Abstract + +The proposed standard allows for the implementation of basic functionality for fixed income financial bonds with smart contracts. +Principal bonds characteristics such as the bond 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 providses a functionality to +allow bonds to be approved by owners in order to be spent by third party. + +## 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. + +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. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +**Every [ERC] compliant contract MUST implement the following ERC- interface** + +```solidity +pragma solidity ^0.8.0; + +/** +* @title ERC- Financial Bonds tandard +*/ +interface IERC { + /** + * @notice Returns the bond isin + */ + function isin() external view returns(string memory); + + /** + * @notice Returs the bond name + */ + function name() external view returns(string memory); + + /** + * @notice Returns the bond symbol + */ + function symbol() external view returns(string memory); + + /** + * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` + * + * OPTIONAL + */ + 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 + */ + 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) 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 bond 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... + */ + function couponType() external view returns(uint256); + + /** + * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. + */ + 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 maturityDate MUST be less than the issueDate + */ + function maturityDate() external view returns(uint256); + + /** + * @notice Returns the day count basis + * Ex: 0: actual/actual, 1: actual/360, etc... + */ + function dayCountBasis() external view returns(uint256); + + /** + * @notice Returns the principal of an account in denomination unit + * Ex: if denomination = $1,000, and the user has invested $5,000 + * then principalOf(_account) = 5,000/1,000 = 5 + * @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. _amount MUST be a multiple of denomination + */ + function approve(address _spender, uint256 _amount) external; + + /** + * @notice Authorizes the `_spender` account to manage all their bonds + * @param _spender the address to be authorized by the bondholder + */ + function approveAll(address _spender) external; + + /** + * @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 + */ + function disapprove(address _spender, uint256 _amount) external; + + /** + * @notice Disapproves `_spender` to manage all the bonds the have been allowed to manage by the caller + * @param _spender the address to remove the authorization by from + */ + function disapproveAll(address _spender) 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 _data additional information provided by the token holder + */ + function transfer(address _to, uint256 _amount, bytes calldata _data) 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 + */ + function transferAll(address _to, bytes calldata _data) external; + + /** + * @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 _data additional information provided by the token holder + */ + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; + + /** + * @notice Moves all bonds from an `_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 + */ + function transferAllFrom(address _from, address _to, bytes calldata _data) external; + + /** + * @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 + */ + event Transferred(address _from, address _to, uint256 _amount, bytes _data); + + /** + * @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. + */ + event Approved(address _owner, address _spender, uint256 _amount); + + /** + * @notice MUST be emmitted when an account is disapproved + * @param _owner the bonds owner + * @param _sepender the account that has been allowed to spend bonds + * @param _amount the amount of tokens to disapprove + */ + event Disapproved(address _owner, address _spender, uint256 _amount); +} +``` + +## Rationale + +The financial bond standard is designed to represennt 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 to 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. + +Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: + +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 bsond 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. + +## Reference Implementation + +The reference implementation will be added in the assets folder + +## Security Considerations + +Will be completed. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 1e35c33b1e3351e725878495cb87d0e24bde5de4 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 29 May 2023 00:49:18 +0200 Subject: [PATCH 02/89] Update eip-financial_bonds.md --- eip-financial_bonds.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eip-financial_bonds.md b/eip-financial_bonds.md index d39ee30928793..928bf79a134eb 100644 --- a/eip-financial_bonds.md +++ b/eip-financial_bonds.md @@ -1,6 +1,6 @@ --- title: Financial Bonds -description: +description: This interface defines a specification for financial bonds tokenization author: Samuel Gwlanold Edoumou (@Edoumou) discussions-to: https://ethereum-magicians.org/t/financial-bonds/14461 status: Draft @@ -30,7 +30,7 @@ and be used by applications like decentrailized exchanges. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every [ERC] compliant contract MUST implement the following ERC- interface** +**Every contract compliant with the EIP MUST implement the following ERC- interface** ```solidity pragma solidity ^0.8.0; @@ -239,11 +239,11 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation will be added in the assets folder +The reference implementation will be added in the assets folder after the PR is merged ## Security Considerations -Will be completed. +When implementing the the ERC, 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. ## Copyright From d1771e5645bc74b29250ef836ffbb660880b098b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 29 May 2023 13:35:47 +0200 Subject: [PATCH 03/89] Update and rename eip-financial_bonds.md to eip-7092.md --- eip-financial_bonds.md => eip-7092.md | 1 + 1 file changed, 1 insertion(+) rename eip-financial_bonds.md => eip-7092.md (99%) diff --git a/eip-financial_bonds.md b/eip-7092.md similarity index 99% rename from eip-financial_bonds.md rename to eip-7092.md index 928bf79a134eb..3c187ecfe0ecf 100644 --- a/eip-financial_bonds.md +++ b/eip-7092.md @@ -1,4 +1,5 @@ --- +eip: 7092 title: Financial Bonds description: This interface defines a specification for financial bonds tokenization author: Samuel Gwlanold Edoumou (@Edoumou) From c03771c87e3fd095c1b8c10cc5721e0d9a2e0d47 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 29 May 2023 15:41:27 +0200 Subject: [PATCH 04/89] Add embedded options logic --- eip-7092.md | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/eip-7092.md b/eip-7092.md index 3c187ecfe0ecf..09cb8cca17bba 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -20,7 +20,7 @@ allow bonds to be approved by owners in order to be spent by third party. ## Motivation -Fixed income instruments is one of the asset classes that is widely used by corporations and other entities to raise funds. Bonds +Fixed income instruments are 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. @@ -31,13 +31,13 @@ and be used by applications like decentrailized exchanges. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every contract compliant with the EIP MUST implement the following ERC- interface** +**Every contract compliant with the EIP-7092 MUST implement the following ERC-7092 interface** ```solidity pragma solidity ^0.8.0; /** -* @title ERC- Financial Bonds tandard +* @title ERC-7092 Financial Bonds tandard */ interface IERC { /** @@ -223,12 +223,14 @@ interface IERC { ## Rationale -The financial bond standard is designed to represennt 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 to 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. +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. Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: @@ -240,7 +242,36 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation will be added in the assets folder after the PR is merged +The reference implementation of EIP-7092 will be added in the assets folder after the PR is merged. + +Some bonds have embedded options attached to them. As an example we can cite: + +1. Callable bonds that have an option that gives right to the issuer to retire bonds before they mature. +2. Puttable bonds that have the option that gives right to investors to retire bonds beforethey mature. +3. Convertible bonds that gives investors the right to convert their bonds to equity. + +Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. + +CALLABLE BONDS: +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Callable is ERC7092 {} +``` + +PUTTABLE BONDS: +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Puttable is ERC7092 {} +``` + +CONVERTIBLE BONDS: +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Convertible is ERC7092 {} +``` ## Security Considerations From bceaf4e1a7ec3baf005a789f9dd1848002dd4faa Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 29 May 2023 15:42:53 +0200 Subject: [PATCH 05/89] Update eip-7092.md --- eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eip-7092.md b/eip-7092.md index 09cb8cca17bba..3ae227a7d192a 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -242,7 +242,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation of EIP-7092 will be added in the assets folder after the PR is merged. +The reference implementation of ERC-7092 will be added in the assets folder after the PR is merged. Some bonds have embedded options attached to them. As an example we can cite: From 09110294eac7a95541f77126d3d069ae0c7e5699 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 29 May 2023 15:54:55 +0200 Subject: [PATCH 06/89] Update eip-7092.md --- eip-7092.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eip-7092.md b/eip-7092.md index 3ae227a7d192a..1ff6df59ce5bd 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -253,6 +253,7 @@ Some bonds have embedded options attached to them. As an example we can cite: Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. CALLABLE BONDS: + ```solidity pragma solidity ^0.8.0; @@ -260,6 +261,7 @@ contract ERC7092Callable is ERC7092 {} ``` PUTTABLE BONDS: + ```solidity pragma solidity ^0.8.0; @@ -267,6 +269,7 @@ contract ERC7092Puttable is ERC7092 {} ``` CONVERTIBLE BONDS: + ```solidity pragma solidity ^0.8.0; From ded056788fe1b99ffc4d8c95e119a78507e07a60 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 12:03:57 +0200 Subject: [PATCH 07/89] change disapprove functions to decreaseAllowance functions --- eip-7092.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eip-7092.md b/eip-7092.md index 1ff6df59ce5bd..c9a5c78e085bf 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -79,14 +79,14 @@ interface IERC { function denomination() external view returns(uint256); /** - * @notice Returns the issue volume (total debt amount) in denomination unit + * @notice Returns the issue volume (total debt amount). It is recommanded 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 bond interest rate in basis point unit + * @notice Returns the bond interest rate. It is recommanded 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 */ @@ -110,7 +110,7 @@ interface IERC { /** * @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 maturityDate MUST be less than the issueDate + * The maturity date MUST be greater than the issue date */ function maturityDate() external view returns(uint256); @@ -121,7 +121,7 @@ interface IERC { function dayCountBasis() external view returns(uint256); /** - * @notice Returns the principal of an account in denomination unit + * @notice Returns the principal of an account. It is recommanded 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 * @param _account account address @@ -154,13 +154,13 @@ interface IERC { * @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 */ - function disapprove(address _spender, uint256 _amount) external; + function decreaseAllowance(address _spender, uint256 _amount) external; /** * @notice Disapproves `_spender` to manage all the bonds the have been allowed to manage by the caller * @param _spender the address to remove the authorization by from */ - function disapproveAll(address _spender) external; + function decreaseAllowanceForAll(address _spender) external; /** * @notice Moves `_amount`bonds to address `_to` From f1aae56b9c81b8928d9ca1ed09fdf1d64f645e0f Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 12:06:05 +0200 Subject: [PATCH 08/89] Update eip-7092.md --- eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eip-7092.md b/eip-7092.md index c9a5c78e085bf..a6bffcd2afb93 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -214,7 +214,7 @@ interface IERC { /** * @notice MUST be emmitted when an account is disapproved * @param _owner the bonds owner - * @param _sepender the account that has been allowed to spend bonds + * @param _spender the account that has been allowed to spend bonds * @param _amount the amount of tokens to disapprove */ event Disapproved(address _owner, address _spender, uint256 _amount); From e344b7a90cae38457059f044fbb4cc64cf9972be Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 12:21:40 +0200 Subject: [PATCH 09/89] update to RECOMMENDED --- eip-7092.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eip-7092.md b/eip-7092.md index a6bffcd2afb93..973390b6e38fa 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -79,14 +79,14 @@ interface IERC { function denomination() external view returns(uint256); /** - * @notice Returns the issue volume (total debt amount). It is recommanded to express the issue volume in denomination unit. + * @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 bond interest rate. It is recommanded 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 point unit. * 1 basis point = 0.01% = 0.0001 * ex: if interest rate = 5%, then coupon() => 500 basis points */ @@ -121,7 +121,7 @@ interface IERC { function dayCountBasis() external view returns(uint256); /** - * @notice Returns the principal of an account. It is recommanded to express the principal in denomination unit. + * @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 * @param _account account address From 3d14ede9fdda295052d0ee6aee4cbc654da1112e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 12:26:40 +0200 Subject: [PATCH 10/89] change IERC to IERC7092 --- eip-7092.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eip-7092.md b/eip-7092.md index 973390b6e38fa..7471a5a3ea41b 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -39,7 +39,7 @@ pragma solidity ^0.8.0; /** * @title ERC-7092 Financial Bonds tandard */ -interface IERC { +interface IERC7092 { /** * @notice Returns the bond isin */ From b850ad34363a72a335d239614444e41300301568 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 15:57:30 +0200 Subject: [PATCH 11/89] change event Disapprove to AllowanceDecreased --- eip-7092.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eip-7092.md b/eip-7092.md index 7471a5a3ea41b..4589f5811b809 100644 --- a/eip-7092.md +++ b/eip-7092.md @@ -150,20 +150,20 @@ interface IERC7092 { function approveAll(address _spender) external; /** - * @notice Lower the allowance of `_spender`by `_amount` + * @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 */ function decreaseAllowance(address _spender, uint256 _amount) external; /** - * @notice Disapproves `_spender` to manage all the bonds the have been allowed to manage by the caller + * @notice Remove the allowance for `_spender` * @param _spender the address to remove the authorization by from */ function decreaseAllowanceForAll(address _spender) external; /** - * @notice Moves `_amount`bonds to address `_to` + * @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 _data additional information provided by the token holder @@ -212,12 +212,12 @@ interface IERC7092 { event Approved(address _owner, address _spender, uint256 _amount); /** - * @notice MUST be emmitted when an account is disapproved + * @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 */ - event Disapproved(address _owner, address _spender, uint256 _amount); + event AllowanceDecreased(address _owner, address _spender, uint256 _amount); } ``` From 289d3f6c5ca1e9f68f35b81a607f70025602d616 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 17:51:01 +0200 Subject: [PATCH 12/89] Create ERC7092.sol in the assets folder --- assets/eip-7092/ERC7092.sol | 272 ++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 assets/eip-7092/ERC7092.sol diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol new file mode 100644 index 0000000000000..74f1b9d4e6cb0 --- /dev/null +++ b/assets/eip-7092/ERC7092.sol @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: MIT +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, + Bond memory _bondInfo, + Issuer memory _issuerInfo + ) { + bondISIN = _bondISIN; + _bondManager = msg.sender; + _bond[_bondISIN] = _bondInfo; + _issuer[_bondISIN] = _issuerInfo; + } + + function issue( + IssueData[] memory _issueData, + Bond memory _bond + ) external onlyBondManager { + _issue(_issueData, _bond); + } + + function redeem() external onlyBondManager { + _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 == 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; + } + + function name() external view returns(string memory) { + return _bond[bondISIN].name; + } + + function symbol() external view returns(string memory) { + return _bond[bondISIN].symbol; + } + + function decimals() external view returns(uint8) { + return _bond[bondISIN].decimals; + } + + function currency() external view returns(address) { + return _bond[bondISIN].currency; + } + + function currencyOfCoupon() external view returns(address) { + return _bond[bondISIN].currencyOfCoupon; + } + + function denomination() public view returns(uint256) { + return _bond[bondISIN].denomination; + } + + function issueVolume() external view returns(uint256) { + return _bond[bondISIN].issueVolume; + } + + function couponRate() external view returns(uint256) { + return _bond[bondISIN].couponRate; + } + + function couponType() external view returns(uint256) { + return _bond[bondISIN].couponType; + } + + function couponFrequency() external view returns(uint256) { + return _bond[bondISIN].couponFrequency; + } + + function issueDate() external view returns(uint256) { + return _bond[bondISIN].issueDate; + } + + function maturityDate() public view returns(uint256) { + return _bond[bondISIN].maturityDate; + } + + function dayCountBasis() external view returns(uint256) { + return _bond[bondISIN].dayCountBasis; + } + + function principalOf(address _account) external view returns(uint256) { + return _principals[_account]; + } + + function approval(address _owner, address _spender) external view returns(uint256) { + return _approvals[_owner][_spender]; + } + + function approve(address _spender, uint256 _amount) external { + address _owner = msg.sender; + + _approve(_owner, _spender, _amount); + } + + function approveAll(address _spender) external { + address _owner = msg.sender; + uint256 _amount = _principals[_owner]; + + _approve(_owner, _spender, _amount); + } + + function decreaseAllowance(address _spender, uint256 _amount) external { + address _owner = msg.sender; + + _disapprove(_owner, _spender, _amount); + } + + function decreaseAllowanceForAll(address _spender) external { + address _owner = msg.sender; + uint256 _amount = _principals[_owner]; + + _disapprove(_owner, _spender, _amount); + } + + function transfer(address _to, uint256 _amount, bytes calldata _data) external { + address _from = msg.sender; + + _transfer(_from, _to, _amount, _data); + } + + function transferAll(address _to, bytes calldata _data) external { + address _from = msg.sender; + uint256 _amount = _principals[_from]; + + _transfer(_from, _to, _amount, _data); + } + + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external { + address _spender = msg.sender; + + _spendApproval(_from, _spender, _amount); + + _transfer(_from, _to, _amount, _data); + } + + function transferAllFrom(address _from, address _to, bytes calldata _data) external { + address _spender = msg.sender; + uint256 _amount = _principals[_from]; + + _spendApproval(_from, _spender, _amount); + + _transfer(_from, _to, _amount, _data); + } + + 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"); + + uint256 principal = _principals[_owner]; + uint256 _approval = _approvals[_owner][_spender]; + uint256 _denomination = denomination(); + uint256 _maturityDate = maturityDate(); + + require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); + require(_amount <= principal, "ERC7092: INSUFFICIENT_BALANCE"); + require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + + _approvals[_owner][_spender] = _approval + _amount; + + emit Approved(_owner, _spender, _amount); + } + + function _disapprove(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"); + + uint256 _approval = _approvals[_owner][_spender]; + uint256 _denomination = denomination(); + uint256 _maturityDate = maturityDate(); + + require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); + require(_amount <= _approval, "ERC7092: NOT_ENOUGH_APPROVAL"); + require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + + _approvals[_owner][_spender] = _approval - _amount; + + emit AllowanceDecreased(_owner, _spender, _amount); + } + + 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(); + + require(block.timestamp < _maturityDate, "ERC7092: BONDS_MATURED"); + require(_amount <= principal, "ERC7092: INSUFFICIENT_BALANCE"); + require(_amount % _denomination == 0, "ERC7092: INVALID_AMOUNT"); + + _beforeBondTransfer(_from, _to, _amount, _data); + + uint256 principalTo = _principals[_to]; + + unchecked { + _principals[_from] = principal - _amount; + _principals[_to] = principalTo + _amount; + } + + emit Transferred(_from, _to, _amount, _data); + + _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"); + + unchecked { + _approvals[_from][_spender] = currentApproval - _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 {} +} From 19b3059f9abf7eec12dd9198368809d5fef8bf65 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 17:57:41 +0200 Subject: [PATCH 13/89] Move eip-7092 in EIPS folder --- EIPS/eip-7092 | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 EIPS/eip-7092 diff --git a/EIPS/eip-7092 b/EIPS/eip-7092 new file mode 100644 index 0000000000000..4589f5811b809 --- /dev/null +++ b/EIPS/eip-7092 @@ -0,0 +1,285 @@ +--- +eip: 7092 +title: Financial Bonds +description: This interface defines a specification for financial bonds tokenization +author: Samuel Gwlanold Edoumou (@Edoumou) +discussions-to: https://ethereum-magicians.org/t/financial-bonds/14461 +status: Draft +type: Standards Track +category: ERC +created: 2023-05-28 +--- + +## Abstract + +The proposed standard allows for the implementation of basic functionality for fixed income financial bonds with smart contracts. +Principal bonds characteristics such as the bond 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 providses a functionality to +allow bonds to be approved by owners in order to be spent by third party. + +## Motivation + +Fixed income instruments are 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. + +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. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +**Every contract compliant with the EIP-7092 MUST implement the following ERC-7092 interface** + +```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 Returs the bond name + */ + function name() external view returns(string memory); + + /** + * @notice Returns the bond symbol + */ + function symbol() external view returns(string memory); + + /** + * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` + * + * OPTIONAL + */ + 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 + */ + 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 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 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... + */ + function couponType() external view returns(uint256); + + /** + * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. + */ + 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... + */ + 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 + * @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. _amount MUST be a multiple of denomination + */ + function approve(address _spender, uint256 _amount) external; + + /** + * @notice Authorizes the `_spender` account to manage all their bonds + * @param _spender the address to be authorized by the bondholder + */ + function approveAll(address _spender) external; + + /** + * @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 + */ + function decreaseAllowance(address _spender, uint256 _amount) external; + + /** + * @notice Remove the allowance for `_spender` + * @param _spender the address to remove the authorization by from + */ + function decreaseAllowanceForAll(address _spender) 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 _data additional information provided by the token holder + */ + function transfer(address _to, uint256 _amount, bytes calldata _data) 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 + */ + function transferAll(address _to, bytes calldata _data) external; + + /** + * @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 _data additional information provided by the token holder + */ + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; + + /** + * @notice Moves all bonds from an `_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 + */ + function transferAllFrom(address _from, address _to, bytes calldata _data) external; + + /** + * @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 + */ + event Transferred(address _from, address _to, uint256 _amount, bytes _data); + + /** + * @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. + */ + event Approved(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 + */ + event AllowanceDecreased(address _owner, address _spender, uint256 _amount); +} +``` + +## 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. + +Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: + +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 bsond 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. + +## Reference Implementation + +The reference implementation of ERC-7092 will be added in the assets folder after the PR is merged. + +Some bonds have embedded options attached to them. As an example we can cite: + +1. Callable bonds that have an option that gives right to the issuer to retire bonds before they mature. +2. Puttable bonds that have the option that gives right to investors to retire bonds beforethey mature. +3. Convertible bonds that gives investors the right to convert their bonds to equity. + +Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. + +CALLABLE BONDS: + +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Callable is ERC7092 {} +``` + +PUTTABLE BONDS: + +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Puttable is ERC7092 {} +``` + +CONVERTIBLE BONDS: + +```solidity +pragma solidity ^0.8.0; + +contract ERC7092Convertible is ERC7092 {} +``` + +## Security Considerations + +When implementing the the ERC, 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. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 7803f6033f40d7b33c495586572e8276928d3efa Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:04:02 +0200 Subject: [PATCH 14/89] Rename eip-7092 to eip-7092.md --- EIPS/{eip-7092 => eip-7092.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-7092 => eip-7092.md} (100%) diff --git a/EIPS/eip-7092 b/EIPS/eip-7092.md similarity index 100% rename from EIPS/eip-7092 rename to EIPS/eip-7092.md From f9f9d82f63099614a5794469803d22a1cf7f1477 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:13:07 +0200 Subject: [PATCH 15/89] Create IERC7092.sol --- assets/eip-7092/IERC7092.sol | 186 +++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 assets/eip-7092/IERC7092.sol diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol new file mode 100644 index 0000000000000..b1a9f959e6041 --- /dev/null +++ b/assets/eip-7092/IERC7092.sol @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: MIT +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 Returs the bond name + */ + function name() external view returns(string memory); + + /** + * @notice Returns the bond symbol + */ + function symbol() external view returns(string memory); + + /** + * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` + * + * OPTIONAL + */ + 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 + */ + 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 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 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... + */ + function couponType() external view returns(uint256); + + /** + * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. + */ + 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... + */ + 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 + * @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. _amount MUST be a multiple of denomination + */ + function approve(address _spender, uint256 _amount) external; + + /** + * @notice Authorizes the `_spender` account to manage all their bonds + * @param _spender the address to be authorized by the bondholder + */ + function approveAll(address _spender) external; + + /** + * @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 + */ + function decreaseAllowance(address _spender, uint256 _amount) external; + + /** + * @notice Remove the allowance for `_spender` + * @param _spender the address to remove the authorization by from + */ + function decreaseAllowanceForAll(address _spender) 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 _data additional information provided by the token holder + */ + function transfer(address _to, uint256 _amount, bytes calldata _data) 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 + */ + function transferAll(address _to, bytes calldata _data) external; + + /** + * @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 _data additional information provided by the token holder + */ + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; + + /** + * @notice Moves all bonds from an `_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 + */ + function transferAllFrom(address _from, address _to, bytes calldata _data) external; + + /** + * @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 + */ + event Transferred(address _from, address _to, uint256 _amount, bytes _data); + + /** + * @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. + */ + event Approved(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 + */ + event AllowanceDecreased(address _owner, address _spender, uint256 _amount); +} From 452ba91355c16974d7a17000789b2b9583094271 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:14:44 +0200 Subject: [PATCH 16/89] Create BondStorage.sol --- assets/eip-7092/BondStorage.sol | 71 +++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 assets/eip-7092/BondStorage.sol diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol new file mode 100644 index 0000000000000..6c4503406bc3e --- /dev/null +++ b/assets/eip-7092/BondStorage.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +contract BondStorage { + struct Bond { + string isin; + 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 { + string name; + string email; + string country; + string headquarters; + string issuerType; + string creditRating; + uint256 carbonCredit; + address issuerAddress; + } + + struct IssueData { + address investor; + uint256 principal; + } + + enum BondStatus {UNREGISTERED, SUBMITTED, ISSUED, REDEEMED} + + mapping(string => Bond) internal _bond; + mapping(string => Issuer) internal _issuer; + mapping(address => uint256) internal _principals; + mapping(address => mapping(address => uint256)) internal _approvals; + + string internal bondISIN; + string internal _countryOfIssuance; + + BondStatus internal _bondStatus; + IssueData[] internal _listOfInvestors; + + address internal _bondManager; + + modifier onlyBondManager { + require(msg.sender == _bondManager, "BondStorage: ONLY_BOND_MANAGER"); + _; + } + 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]; + } +} From b5b003a89ead536d69f1db191191cd86e2d987b5 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:22:14 +0200 Subject: [PATCH 17/89] Update eip-7092.md --- 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 4589f5811b809..1e6e895e17e68 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -31,7 +31,7 @@ and be used by applications like decentrailized exchanges. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every contract compliant with the EIP-7092 MUST implement the following ERC-7092 interface** +**Every contract compliant with the [EIP-7092](./eip-7092) MUST implement the following interface** ```solidity pragma solidity ^0.8.0; From b2ccf25c6845994313c4dcd569faff4a3ee7023b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:26:51 +0200 Subject: [PATCH 18/89] Update eip-7092.md --- 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 1e6e895e17e68..0250058c5f277 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -242,7 +242,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation of ERC-7092 will be added in the assets folder after the PR is merged. +The reference implementation of [ERC-7092](./eip-7092) can be found [here](../assets/ERC7092.sol). Some bonds have embedded options attached to them. As an example we can cite: From 52584f8e45d4a76643420da7421f0c4852c26a6f Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:29:10 +0200 Subject: [PATCH 19/89] Update eip-7092.md --- 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 0250058c5f277..952074fdac1fc 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -31,7 +31,7 @@ and be used by applications like decentrailized exchanges. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every contract compliant with the [EIP-7092](./eip-7092) MUST implement the following interface** +**Every contract compliant with the [ERC-7092](./eip-7092) MUST implement the following interface** ```solidity pragma solidity ^0.8.0; From 49087ac8f4d8617f356e114de72bb53f0a6b75bc Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 18:39:59 +0200 Subject: [PATCH 20/89] Update eip-7092.md --- 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 952074fdac1fc..0c7d30877a3af 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -242,7 +242,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation of [ERC-7092](./eip-7092) can be found [here](../assets/ERC7092.sol). +The reference implementation of [ERC-7092](./eip-7092) can be found [here](../assets/eip-7092/ERC7092.sol). Some bonds have embedded options attached to them. As an example we can cite: From 595a551b20d2828ee7811a5613a0bffb52db9457 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 19:39:50 +0200 Subject: [PATCH 21/89] updates ref --- 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 0c7d30877a3af..2b46c3edc6fb6 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -242,7 +242,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation of [ERC-7092](./eip-7092) can be found [here](../assets/eip-7092/ERC7092.sol). +The reference implementation of this standard can be found [here](../assets/eip-7092/ERC7092.sol). Some bonds have embedded options attached to them. As an example we can cite: From 31553893bd78c79a0707d0610b00fe560e2115e7 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 19:41:42 +0200 Subject: [PATCH 22/89] Update ref --- 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 2b46c3edc6fb6..b02f75a7551f5 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -31,7 +31,7 @@ and be used by applications like decentrailized exchanges. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. -**Every contract compliant with the [ERC-7092](./eip-7092) MUST implement the following interface** +**Every contract compliant with the [ERC-7092](./eip-7092.md) MUST implement the following interface** ```solidity pragma solidity ^0.8.0; @@ -242,7 +242,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu ## Reference Implementation -The reference implementation of this standard can be found [here](../assets/eip-7092/ERC7092.sol). +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: From 5deeeb38a54d16afc2e6b3714eaeb319fe03ea9d Mon Sep 17 00:00:00 2001 From: Edoumou Date: Tue, 30 May 2023 19:45:34 +0200 Subject: [PATCH 23/89] remove md file in the EIP root --- eip-7092.md | 285 ---------------------------------------------------- 1 file changed, 285 deletions(-) delete mode 100644 eip-7092.md diff --git a/eip-7092.md b/eip-7092.md deleted file mode 100644 index 4589f5811b809..0000000000000 --- a/eip-7092.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -eip: 7092 -title: Financial Bonds -description: This interface defines a specification for financial bonds tokenization -author: Samuel Gwlanold Edoumou (@Edoumou) -discussions-to: https://ethereum-magicians.org/t/financial-bonds/14461 -status: Draft -type: Standards Track -category: ERC -created: 2023-05-28 ---- - -## Abstract - -The proposed standard allows for the implementation of basic functionality for fixed income financial bonds with smart contracts. -Principal bonds characteristics such as the bond 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 providses a functionality to -allow bonds to be approved by owners in order to be spent by third party. - -## Motivation - -Fixed income instruments are 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. - -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. - -## Specification - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. - -**Every contract compliant with the EIP-7092 MUST implement the following ERC-7092 interface** - -```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 Returs the bond name - */ - function name() external view returns(string memory); - - /** - * @notice Returns the bond symbol - */ - function symbol() external view returns(string memory); - - /** - * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` - * - * OPTIONAL - */ - 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 - */ - 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 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 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... - */ - function couponType() external view returns(uint256); - - /** - * @notice Returns the coupon frequency, i.e. the number of times coupons are paid in a year. - */ - 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... - */ - 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 - * @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. _amount MUST be a multiple of denomination - */ - function approve(address _spender, uint256 _amount) external; - - /** - * @notice Authorizes the `_spender` account to manage all their bonds - * @param _spender the address to be authorized by the bondholder - */ - function approveAll(address _spender) external; - - /** - * @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 - */ - function decreaseAllowance(address _spender, uint256 _amount) external; - - /** - * @notice Remove the allowance for `_spender` - * @param _spender the address to remove the authorization by from - */ - function decreaseAllowanceForAll(address _spender) 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 _data additional information provided by the token holder - */ - function transfer(address _to, uint256 _amount, bytes calldata _data) 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 - */ - function transferAll(address _to, bytes calldata _data) external; - - /** - * @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 _data additional information provided by the token holder - */ - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; - - /** - * @notice Moves all bonds from an `_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 - */ - function transferAllFrom(address _from, address _to, bytes calldata _data) external; - - /** - * @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 - */ - event Transferred(address _from, address _to, uint256 _amount, bytes _data); - - /** - * @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. - */ - event Approved(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 - */ - event AllowanceDecreased(address _owner, address _spender, uint256 _amount); -} -``` - -## 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. - -Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: - -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 bsond 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. - -## Reference Implementation - -The reference implementation of ERC-7092 will be added in the assets folder after the PR is merged. - -Some bonds have embedded options attached to them. As an example we can cite: - -1. Callable bonds that have an option that gives right to the issuer to retire bonds before they mature. -2. Puttable bonds that have the option that gives right to investors to retire bonds beforethey mature. -3. Convertible bonds that gives investors the right to convert their bonds to equity. - -Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. - -CALLABLE BONDS: - -```solidity -pragma solidity ^0.8.0; - -contract ERC7092Callable is ERC7092 {} -``` - -PUTTABLE BONDS: - -```solidity -pragma solidity ^0.8.0; - -contract ERC7092Puttable is ERC7092 {} -``` - -CONVERTIBLE BONDS: - -```solidity -pragma solidity ^0.8.0; - -contract ERC7092Convertible is ERC7092 {} -``` - -## Security Considerations - -When implementing the the ERC, 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. - -## Copyright - -Copyright and related rights waived via [CC0](../LICENSE.md). From 1813eea9600dc2816c5ca33e68d5c504515dc0ba Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 30 May 2023 20:19:06 +0200 Subject: [PATCH 24/89] change disapprove to decreaseAllowance --- assets/eip-7092/ERC7092.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index 74f1b9d4e6cb0..9ca39a7b5d484 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -153,14 +153,14 @@ contract ERC7092 is IERC7092, BondStorage { function decreaseAllowance(address _spender, uint256 _amount) external { address _owner = msg.sender; - _disapprove(_owner, _spender, _amount); + _decreaseAllowance(_owner, _spender, _amount); } function decreaseAllowanceForAll(address _spender) external { address _owner = msg.sender; uint256 _amount = _principals[_owner]; - _disapprove(_owner, _spender, _amount); + _decreaseAllowance(_owner, _spender, _amount); } function transfer(address _to, uint256 _amount, bytes calldata _data) external { @@ -212,7 +212,7 @@ contract ERC7092 is IERC7092, BondStorage { emit Approved(_owner, _spender, _amount); } - function _disapprove(address _owner, address _spender, uint256 _amount) internal virtual { + function _decreaseAllowance(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"); From abc560c4eb0575091d07fbae5cafc4230edea0bd Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 10:09:03 +0200 Subject: [PATCH 25/89] Update eip-7092.md --- EIPS/eip-7092.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index b02f75a7551f5..b9cd1dbb1e40a 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -236,7 +236,7 @@ Tokenizing bonds will offer several advantages compared to traditional bond issu 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 bsond market. +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. @@ -246,8 +246,8 @@ The reference implementation of the [ERC-7092](./eip-7092.md) can be found [here Some bonds have embedded options attached to them. As an example we can cite: -1. Callable bonds that have an option that gives right to the issuer to retire bonds before they mature. -2. Puttable bonds that have the option that gives right to investors to retire bonds beforethey mature. +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. Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. @@ -257,6 +257,8 @@ CALLABLE BONDS: ```solidity pragma solidity ^0.8.0; +import 'ERC7092.sol'; + contract ERC7092Callable is ERC7092 {} ``` @@ -265,6 +267,8 @@ PUTTABLE BONDS: ```solidity pragma solidity ^0.8.0; +import 'ERC7092.sol'; + contract ERC7092Puttable is ERC7092 {} ``` @@ -273,12 +277,14 @@ CONVERTIBLE BONDS: ```solidity pragma solidity ^0.8.0; +import 'ERC7092.sol'; + contract ERC7092Convertible is ERC7092 {} ``` ## Security Considerations -When implementing the the ERC, 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, 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. ## Copyright From f19c2d0600663a07265f65188615eba028e24bbc Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 11:45:53 +0200 Subject: [PATCH 26/89] Create CouponMath.sol --- assets/eip-7092/coupons/CouponMath.sol | 54 ++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 assets/eip-7092/coupons/CouponMath.sol diff --git a/assets/eip-7092/coupons/CouponMath.sol b/assets/eip-7092/coupons/CouponMath.sol new file mode 100644 index 0000000000000..ccd9c905b024c --- /dev/null +++ b/assets/eip-7092/coupons/CouponMath.sol @@ -0,0 +1,54 @@ +pragma solidity ^0.8.0; + +import "../IERC7092.sol"; + +library CouponMath { + /** + * @notice Returns the annual interest earned by an account in bips + * @param _investor the investor account address + * @param _bondContract the bond contract address + */ + function annualInterest( + address _investor, + address _bondContract + ) external view returns(uint256) { + uint256 couponRate = IERC(_bondContract).couponRate(); + uint256 denomination = IERC(_bondContract).denomination(); + uint256 principal = IERC(_bondContract).principalOf(_investor); + + return principal * denomination * couponRate; + } + + /** + * @notice Returns the interest earned by an account in period `_duration` in bips + * @param _investor the investor account address + * @param _duration time ellapsed since the last coupon payment + * @param _bondContract the bond contract address + */ + function interest( + address _investor, + uint256 _duration, + address _bondContract + ) external view returns(uint256) { + uint256 couponRate = IERC(_bondContract).couponRate(); + uint256 couponDenomination = IERC(_bondContract).denomination(); + uint256 principal = IERC(_bondContract).principalOf(_investor); + uint256 frequency = IERC(_bondContract).couponFrequency(); + uint256 numberOfDays = _numberOfDays(_bondContract); + + return principal * couponDenomination * couponRate * _duration / (frequency * numberOfDays); + } + + + function _numberOfDays(address _bondContract) private view returns(uint256) { + uint256 dayCountBasis = IERC(_bondContract).dayCountBasis(); + + if(dayCountBasis == 0) { + return 365; + } else if(dayCountBasis == 1) { + return 360; + } else { + revert("invalid day count basis value"); + } + } +} From 562ef59a8fc2a30e509a00f77c604eefdd4ff6b2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 11:52:13 +0200 Subject: [PATCH 27/89] change EIP to EIP7092 in CouponMath.sol --- assets/eip-7092/coupons/CouponMath.sol | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assets/eip-7092/coupons/CouponMath.sol b/assets/eip-7092/coupons/CouponMath.sol index ccd9c905b024c..9f8eaeb74dbe7 100644 --- a/assets/eip-7092/coupons/CouponMath.sol +++ b/assets/eip-7092/coupons/CouponMath.sol @@ -12,9 +12,9 @@ library CouponMath { address _investor, address _bondContract ) external view returns(uint256) { - uint256 couponRate = IERC(_bondContract).couponRate(); - uint256 denomination = IERC(_bondContract).denomination(); - uint256 principal = IERC(_bondContract).principalOf(_investor); + uint256 couponRate = IERC7092(_bondContract).couponRate(); + uint256 denomination = IERC7092(_bondContract).denomination(); + uint256 principal = IERC7092(_bondContract).principalOf(_investor); return principal * denomination * couponRate; } @@ -30,18 +30,21 @@ library CouponMath { uint256 _duration, address _bondContract ) external view returns(uint256) { - uint256 couponRate = IERC(_bondContract).couponRate(); - uint256 couponDenomination = IERC(_bondContract).denomination(); - uint256 principal = IERC(_bondContract).principalOf(_investor); - uint256 frequency = IERC(_bondContract).couponFrequency(); + uint256 couponRate = IERC7092(_bondContract).couponRate(); + uint256 couponDenomination = IERC7092(_bondContract).denomination(); + uint256 principal = IERC7092(_bondContract).principalOf(_investor); + uint256 frequency = IERC7092(_bondContract).couponFrequency(); uint256 numberOfDays = _numberOfDays(_bondContract); return principal * couponDenomination * couponRate * _duration / (frequency * numberOfDays); } - + /** + * @notice Returns the number of days in a year based on the base count basis used. + * Here we just check for two values. + */ function _numberOfDays(address _bondContract) private view returns(uint256) { - uint256 dayCountBasis = IERC(_bondContract).dayCountBasis(); + uint256 dayCountBasis = IERC7092(_bondContract).dayCountBasis(); if(dayCountBasis == 0) { return 365; From 79ed8a655fcf4f87827e2a082b957f04c7ad5c2e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 13:55:14 +0200 Subject: [PATCH 28/89] Update BondStorage.sol --- assets/eip-7092/BondStorage.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index 6c4503406bc3e..3b2bb03782dc3 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -54,6 +54,7 @@ contract BondStorage { require(msg.sender == _bondManager, "BondStorage: ONLY_BOND_MANAGER"); _; } + event BondIssued(IssueData[] _issueData, Bond _bond); event BondRedeemed(); From ec29ff99e743212d61a52732e5d35bab1e154fd7 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 14:23:23 +0200 Subject: [PATCH 29/89] Update embedded options functions --- EIPS/eip-7092.md | 54 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index b9cd1dbb1e40a..89c6f3855482b 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -259,7 +259,23 @@ pragma solidity ^0.8.0; import 'ERC7092.sol'; -contract ERC7092Callable is ERC7092 {} +contract ERC7092Callable is ERC7092 { + // WRITE THE LOGIC TO ALLOW THE ISSUER TO CALL BONDS + // STATE VARIABLES AND FUNCTIONS NEEDED + + /** + * @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(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Callable: BOND_MATURED"); + + _principals[_investor] = 0; + + // ADD LOGIC HERE + } +} ``` PUTTABLE BONDS: @@ -269,7 +285,23 @@ pragma solidity ^0.8.0; import 'ERC7092.sol'; -contract ERC7092Puttable is ERC7092 {} +contract ERC7092Puttable is ERC7092 { + // WRITE THE LOGIC TO ALLOW INVESTORS TO PUT BONDS + // STATE VARIABLES AND FUNCTIONS NEEDED + + /** + * @notice put bonds + * MUST be called by investors who own bonds + */ + function put() public { + require(_principals[msg.sender] > 0, "ERC7092Puttable: ONLY_INVESTORS"); + require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Puttable: BOND_MATURED"); + + _principals[msg.sender] = 0; + + // ADD LOGIC + } +} ``` CONVERTIBLE BONDS: @@ -279,7 +311,23 @@ pragma solidity ^0.8.0; import 'ERC7092.sol'; -contract ERC7092Convertible is ERC7092 {} +contract ERC7092Convertible is ERC7092 { + // WRITE THE LOGIC TO ALLOW INVESTOR OR ISSUER TO CONVERT BONDS TO EQUITY + // STATE VARIABLES AND FUNCTIONS NEEDED + + /** + * @notice convert bonds to equity. Here we assumed that the investors must convert their bonds to equity + * Issuer can also convert invetsors bonds to equity. + */ + function convert() public { + require(_principals[msg.sender] > 0, "ERC7092Convertible: ONLY_INVESTORS"); + require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Convertible: BOND_MATURED"); + + _principals[msg.sender] = 0; + + // ADD LOGIC HERE + } +} ``` ## Security Considerations From e40a0e2b7daa0449a87ea15986912401ef50df98 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 16:57:47 +0200 Subject: [PATCH 30/89] Update ERC7092.sol --- assets/eip-7092/ERC7092.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index 9ca39a7b5d484..3651eee8259e3 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -10,12 +10,10 @@ import "./BondStorage.sol"; contract ERC7092 is IERC7092, BondStorage { constructor( string memory _bondISIN, - Bond memory _bondInfo, Issuer memory _issuerInfo ) { bondISIN = _bondISIN; _bondManager = msg.sender; - _bond[_bondISIN] = _bondInfo; _issuer[_bondISIN] = _issuerInfo; } From 09c84e51ae39c6c49abbd80d9f01cd99f25d3682 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 31 May 2023 17:28:12 +0200 Subject: [PATCH 31/89] Update BondStorage.sol --- assets/eip-7092/BondStorage.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index 3b2bb03782dc3..045fa941f61dd 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -69,4 +69,8 @@ contract BondStorage { function bondInfo() public view returns(Bond memory) { return _bond[bondISIN]; } + + function issuerInfo() public view returns(Issuer memory) { + return _issuer[bondISIN]; + } } From 17517249d0bcff9c5f3d1f68c6e2fd5fe735db8f Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:22:39 +0200 Subject: [PATCH 32/89] Update contracts with embeded options --- EIPS/eip-7092.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 89c6f3855482b..1781b9fdcf7ef 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -271,6 +271,7 @@ contract ERC7092Callable is ERC7092 { require(_principals[_investor] > 0, "ERC7092Callable: ONLY_ISSUER"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Callable: BOND_MATURED"); + uint256 principal = _principals[_investor]; _principals[_investor] = 0; // ADD LOGIC HERE @@ -297,6 +298,7 @@ contract ERC7092Puttable is ERC7092 { require(_principals[msg.sender] > 0, "ERC7092Puttable: ONLY_INVESTORS"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Puttable: BOND_MATURED"); + uint256 principal = _principals[_investor]; _principals[msg.sender] = 0; // ADD LOGIC @@ -323,6 +325,7 @@ contract ERC7092Convertible is ERC7092 { require(_principals[msg.sender] > 0, "ERC7092Convertible: ONLY_INVESTORS"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Convertible: BOND_MATURED"); + uint256 principal = _principals[_investor]; _principals[msg.sender] = 0; // ADD LOGIC HERE From 2008a086d2efe06365435fd7a50eb6b25d1d11e6 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:24:19 +0200 Subject: [PATCH 33/89] wip --- 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 1781b9fdcf7ef..287ae3c938803 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -298,7 +298,7 @@ contract ERC7092Puttable is ERC7092 { require(_principals[msg.sender] > 0, "ERC7092Puttable: ONLY_INVESTORS"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Puttable: BOND_MATURED"); - uint256 principal = _principals[_investor]; + uint256 principal = _principals[msg.sender]; _principals[msg.sender] = 0; // ADD LOGIC @@ -325,7 +325,7 @@ contract ERC7092Convertible is ERC7092 { require(_principals[msg.sender] > 0, "ERC7092Convertible: ONLY_INVESTORS"); require(block.timestamp < _bond[bondISIN].maturityDate, "ERC7092Convertible: BOND_MATURED"); - uint256 principal = _principals[_investor]; + uint256 principal = _principals[msg.sender]; _principals[msg.sender] = 0; // ADD LOGIC HERE From bc6a9a32fa3f6c4fb5cc7aae5e5ff8af81978239 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 13 Jun 2023 16:49:09 +0200 Subject: [PATCH 34/89] fix a couple of typos As proposed by @fosgate29 --- 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 b1a9f959e6041..b4dbeca06c6a3 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -11,7 +11,7 @@ interface IERC7092 { function isin() external view returns(string memory); /** - * @notice Returs the bond name + * @notice Returns the bond name */ function name() external view returns(string memory); @@ -21,7 +21,7 @@ interface IERC7092 { function symbol() external view returns(string memory); /** - * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` + * @notice Returns the number of decimals the bond uses - e.g `10`, means to divide the token amount by `10000000000` * * OPTIONAL */ @@ -38,8 +38,8 @@ 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 + * @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); @@ -115,14 +115,14 @@ interface IERC7092 { function approveAll(address _spender) external; /** - * @notice Lower the allowance of `_spender` by `_amount` + * @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 */ function decreaseAllowance(address _spender, uint256 _amount) external; /** - * @notice Remove the allowance for `_spender` + * @notice Removes the allowance for `_spender` * @param _spender the address to remove the authorization by from */ function decreaseAllowanceForAll(address _spender) external; @@ -143,7 +143,7 @@ interface IERC7092 { function transferAll(address _to, bytes calldata _data) external; /** - * @notice Moves `_amount` bonds from an account that has authorized through the approve function + * @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 to transfer. _amount MUST be a multiple of denomination @@ -152,7 +152,7 @@ interface IERC7092 { function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; /** - * @notice Moves all bonds from an `_from` to `_to`. The caller must have been authorized through the approve function + * @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 From 6b1e4b3ce5fa2f14c87d05cffd0cb9fcdb81fc07 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 4 Jul 2023 12:52:39 +0200 Subject: [PATCH 35/89] change transfers functions to return a boolean --- 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 287ae3c938803..924d6af3f097c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -168,14 +168,14 @@ interface IERC7092 { * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination * @param _data additional information provided by the token holder */ - function transfer(address _to, uint256 _amount, bytes calldata _data) external; + function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** * @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 */ - function transferAll(address _to, bytes calldata _data) external; + function transferAll(address _to, bytes calldata _data) external returns(bool); /** * @notice Moves `_amount` bonds from an account that has authorized through the approve function @@ -184,7 +184,7 @@ interface IERC7092 { * @param _amount amount of bond to transfer. _amount MUST be a multiple of denomination * @param _data additional information provided by the token holder */ - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external; + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** * @notice Moves all bonds from an `_from` to `_to`. The caller must have been authorized through the approve function @@ -192,7 +192,7 @@ interface IERC7092 { * @param _to the address to transfer bonds to * @param _data additional information provided by the token holder */ - function transferAllFrom(address _from, address _to, bytes calldata _data) external; + function transferAllFrom(address _from, address _to, bytes calldata _data) external returns(bool); /** * @notice MUST be emitted when bonds are transferred From 59ebe03cd8923917611d7f5485d37bd51f912dc2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 4 Jul 2023 12:55:07 +0200 Subject: [PATCH 36/89] change _transfer function to return a bioolean --- assets/eip-7092/ERC7092.sol | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index 3651eee8259e3..ffbfdf05d5c94 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -161,20 +161,20 @@ contract ERC7092 is IERC7092, BondStorage { _decreaseAllowance(_owner, _spender, _amount); } - function transfer(address _to, uint256 _amount, bytes calldata _data) external { + function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool) { address _from = msg.sender; _transfer(_from, _to, _amount, _data); } - function transferAll(address _to, bytes calldata _data) external { + function transferAll(address _to, bytes calldata _data) external returns(bool) { address _from = msg.sender; uint256 _amount = _principals[_from]; _transfer(_from, _to, _amount, _data); } - function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external { + function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool) { address _spender = msg.sender; _spendApproval(_from, _spender, _amount); @@ -182,7 +182,7 @@ contract ERC7092 is IERC7092, BondStorage { _transfer(_from, _to, _amount, _data); } - function transferAllFrom(address _from, address _to, bytes calldata _data) external { + function transferAllFrom(address _from, address _to, bytes calldata _data) external returns(bool) { address _spender = msg.sender; uint256 _amount = _principals[_from]; @@ -253,6 +253,8 @@ contract ERC7092 is IERC7092, BondStorage { emit Transferred(_from, _to, _amount, _data); _afterBondTransfer(_from, _to, _amount, _data); + + return true; } function _spendApproval(address _from, address _spender, uint256 _amount) internal virtual { From 547cb977237735f95fb1dbc71a60f652cd819b00 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 11 Jul 2023 22:36:47 +0200 Subject: [PATCH 37/89] implement a third level heading for bonds embedded options title --- EIPS/eip-7092.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 924d6af3f097c..292a7ec49f686 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -252,7 +252,7 @@ Some bonds have embedded options attached to them. As an example we can cite: Bonds with embedded options can be created by inheriting from the basic ERC-7092 that integrates the proposed interface. -CALLABLE BONDS: +### CALLABLE BONDS: ```solidity pragma solidity ^0.8.0; @@ -279,7 +279,7 @@ contract ERC7092Callable is ERC7092 { } ``` -PUTTABLE BONDS: +### PUTTABLE BONDS: ```solidity pragma solidity ^0.8.0; @@ -306,7 +306,7 @@ contract ERC7092Puttable is ERC7092 { } ``` -CONVERTIBLE BONDS: +### CONVERTIBLE BONDS: ```solidity pragma solidity ^0.8.0; From 11b9ab92d20ec1e84f8b076d45a1f162efcdae21 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:39:39 +0200 Subject: [PATCH 38/89] update specs --- EIPS/eip-7092.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 292a7ec49f686..8617fa08ca0e8 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -1,7 +1,7 @@ --- eip: 7092 title: Financial Bonds -description: This interface defines a specification for financial bonds tokenization +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 @@ -12,11 +12,10 @@ created: 2023-05-28 ## Abstract -The proposed standard allows for the implementation of basic functionality for fixed income financial bonds with smart contracts. -Principal bonds characteristics such as the bond 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 providses a functionality to -allow bonds to be approved by owners in order to be spent by third party. +This proposal introduces fixed income financial bonds. Important bonds 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. ## Motivation @@ -27,6 +26,23 @@ 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. +The existing standard [ERC-3475](https://eips.ethereum.org/EIPS/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 for each parameter. + +By keeping same standards as with traditional bonds, the ERC-7092 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. + +Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: + +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. + ## Specification The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. From b923f8ee21e43ff08b9bc9b8abc333c5e4bc7c2e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 11 Jul 2023 23:41:39 +0200 Subject: [PATCH 39/89] update motivation --- 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 8617fa08ca0e8..5180e81a83a5e 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -30,7 +30,7 @@ The existing standard [ERC-3475](https://eips.ethereum.org/EIPS/eip-3475) that m 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 for each parameter. +need to rember which metadata is assigned to each parameter. By keeping same standards as with traditional bonds, the ERC-7092 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. From b9d0ed33828661d4089e6972d7b0a77cc716de6e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 00:48:27 +0200 Subject: [PATCH 40/89] update rational --- EIPS/eip-7092.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 5180e81a83a5e..a999d93aa5ced 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -248,13 +248,18 @@ institutional issuance, the smart contracts can be managed by the investment ban 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. -Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: +Thge `totalSupply` function is not included since it can be calculated from the `issueVolume` and the bond `denomination`. The `balanceOf` function +used in other standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) is not +included since it can be calculated from the tokenholder `principal` and the bond `denomination`. + +We have added the `data` input in all `transfer` functions to allow the transfer of additional data attached to the bond token. + +### Backwards compatibility + +Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standard, +like [ERC-20](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155), the ERC-7092 is a +representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. -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. ## Reference Implementation From 768913a8b84d8118c0de421ae2b1baf0cb944ef4 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 00:53:41 +0200 Subject: [PATCH 41/89] update --- 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 a999d93aa5ced..0caa058ec1f5e 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -32,7 +32,7 @@ traditional entities to migrate to tokenized bonds. Morever, the use of on-chain 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. -By keeping same standards as with traditional bonds, the ERC-7092 allows to create a new token for bonds with same caracteristics as traditional bonds so as to make it simple +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. Tokenizing bonds will offer several advantages compared to traditional bond issuance and trading, among with: From a788b53f434eba7b6940a59445f920df07cb5dff Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:00:47 +0200 Subject: [PATCH 42/89] Update eip-7092 --- 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 0caa058ec1f5e..17762d05c908c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -27,8 +27,8 @@ This standard interface allows fixed income instruments to be represented as on- and be used by applications like decentrailized exchanges. The existing standard [ERC-3475](https://eips.ethereum.org/EIPS/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__ +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. From b7e609d96454c4ec63a64aa449f911e6b8020580 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:04:34 +0200 Subject: [PATCH 43/89] Update eip-7092.md --- 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 17762d05c908c..f914c36c33af2 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -26,7 +26,7 @@ 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. -The existing standard [ERC-3475](https://eips.ethereum.org/EIPS/eip-3475) that may be used to create abstract storage bonds does not follow same standards as +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 @@ -249,7 +249,7 @@ to list bonds, in that case, decentralized exchanges will be in charge of managi tokenized bonds by integrating this financial bond interface. Thge `totalSupply` function is not included since it can be calculated from the `issueVolume` and the bond `denomination`. The `balanceOf` function -used in other standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) is not +used in other standards like [ERC-20](./eip-721) and [ERC-1155](./eip-1155) is not included since it can be calculated from the tokenholder `principal` and the bond `denomination`. We have added the `data` input in all `transfer` functions to allow the transfer of additional data attached to the bond token. @@ -257,8 +257,8 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standard, -like [ERC-20](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155), the ERC-7092 is a -representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. +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 chracateristics +and functionalities already attached to it. ## Reference Implementation From dca3c9504722b8443c1a7264c61b10c40bad2436 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:15:02 +0200 Subject: [PATCH 44/89] Update eip-7092.md --- EIPS/eip-7092.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index f914c36c33af2..63044a28f18b1 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -260,6 +260,9 @@ Beacause some of functions like `totalSupply` or `balanceOf` are not implemented 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 chracateristics and functionalities already attached to it. +*__For the reasons mentionned above, we recommand a pure implementation of the standard__* to issue tokenized bonds, since any hybrid solution +with other standard like ERC-20 will fail. + ## Reference Implementation From d91b24192f058ca3c0f5c9a46ed984af5a7630cc Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:17:06 +0200 Subject: [PATCH 45/89] Update eip-7092.md --- 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 63044a28f18b1..bd173ac4efe2c 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -261,7 +261,7 @@ like [ERC-20](./eip-20) or [ERC-1155](./eip-1155), the ERC-7092 is a representat and functionalities already attached to it. *__For the reasons mentionned above, we recommand a pure implementation of the standard__* to issue tokenized bonds, since any hybrid solution -with other standard like ERC-20 will fail. +with other standard mentionned above will fail. ## Reference Implementation From 11bbc0b53bae17caf8b89337efb05bc820208ff0 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:19:20 +0200 Subject: [PATCH 46/89] Update eip-7092.md --- 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 bd173ac4efe2c..a8097f36ba9b0 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -260,7 +260,7 @@ Beacause some of functions like `totalSupply` or `balanceOf` are not implemented 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 chracateristics and functionalities already attached to it. -*__For the reasons mentionned above, we recommand a pure implementation of the standard__* to issue tokenized bonds, since any hybrid solution +**_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution with other standard mentionned above will fail. From ac6d577df6b7d177dbb5e20e1d70b11b3bc03a10 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:33:39 +0200 Subject: [PATCH 47/89] Update eip-7092.md --- 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 a8097f36ba9b0..3d72aea901a5a 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -261,7 +261,7 @@ like [ERC-20](./eip-20) or [ERC-1155](./eip-1155), the ERC-7092 is a representat and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution -with other standard mentionned above will fail. +with other standard mentionned above SHOULD fail. ## Reference Implementation From eb8b5f2ab47a2f990c4c464fcd77f646ac7eb15b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:34:58 +0200 Subject: [PATCH 48/89] Update eip-7092.md --- 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 3d72aea901a5a..b8585cff9eac5 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -257,7 +257,7 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standard, -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 chracateristics +like ERC-20 or ERC-1155, the ERC-7092 is a representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution From 3feb68d4d380d4256e0fb86180f33f2e4de6d65a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:35:38 +0200 Subject: [PATCH 49/89] Update eip-7092.md --- 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 b8585cff9eac5..4499b7069798b 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -256,7 +256,7 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility -Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standard, +Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, like ERC-20 or ERC-1155, the ERC-7092 is a representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. From a46ae1a8dd0323e7dffad712d475ca5fa67d90ba Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:36:13 +0200 Subject: [PATCH 50/89] Update eip-7092.md --- 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 4499b7069798b..06eccb44a2f54 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -256,7 +256,7 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility -Beacause some of functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, +Beacause some functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, like ERC-20 or ERC-1155, the ERC-7092 is a representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. From 8b40631bc3c12c3fec6faefa112f06d3b2df7cda Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:36:56 +0200 Subject: [PATCH 51/89] Update eip-7092.md --- 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 06eccb44a2f54..45641ec0a8cbf 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -257,7 +257,7 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility Beacause some functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, -like ERC-20 or ERC-1155, the ERC-7092 is a representation of a new token for bonds with all bonds chracateristics +like ERC-20 or ERC-1155; The ERC-7092 is a representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution From 0acad771166249cabd9e6c7d62bf653738090296 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:37:21 +0200 Subject: [PATCH 52/89] Update eip-7092.md --- 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 45641ec0a8cbf..877864c45055e 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -257,7 +257,7 @@ We have added the `data` input in all `transfer` functions to allow the transfer ### Backwards compatibility Beacause some functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, -like ERC-20 or ERC-1155; The ERC-7092 is a representation of a new token for bonds with all bonds chracateristics +like ERC-20 or ERC-1155. The ERC-7092 is a representation of a new token for bonds with all bonds chracateristics and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution From b1808c8d2ed9b6c4113039178b5fca0a15099ec4 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:40:37 +0200 Subject: [PATCH 53/89] update rationale --- 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 877864c45055e..b236be2f87b88 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -261,7 +261,7 @@ like ERC-20 or ERC-1155. The ERC-7092 is a representation of a new token for bon and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution -with other standard mentionned above SHOULD fail. +with other standards mentionned above SHOULD fail. ## Reference Implementation From cc09ae791f1d6bc4ab9a6ce8632bb7765f760aa4 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 20:00:12 +0200 Subject: [PATCH 54/89] return boolean for approve function --- 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 b236be2f87b88..12d31bead0ec1 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -157,7 +157,7 @@ interface IERC7092 { * @param _spender the address to be authorized by the bondholder * @param _amount amount of bond to approve. _amount MUST be a multiple of denomination */ - 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 From 16aa28bb5933d95b9d6d08819faf88eedf9a6a15 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 20:14:06 +0200 Subject: [PATCH 55/89] Update eip-7092.md --- EIPS/eip-7092.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 12d31bead0ec1..d11345495d296 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -98,6 +98,7 @@ 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 + * NOTICE: The `issue volume` in denomination unit MUST be equal to the `totalSupply` of the bonds, i.e. the total number of bond tokens issued. */ function issueVolume() external view returns(uint256); @@ -126,7 +127,7 @@ interface IERC7092 { /** * @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 + * The` maturity date` MUST be greater than the `issue date` */ function maturityDate() external view returns(uint256); @@ -140,6 +141,7 @@ interface IERC7092 { * @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: The `principal` in denomination unit MUST be equal to the `balance` of an account, i.e. the number of bond tokens owned by an account. * @param _account account address */ function principalOf(address _account) external view returns(uint256); @@ -203,7 +205,7 @@ interface IERC7092 { function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool); /** - * @notice Moves all bonds from an `_from` to `_to`. The caller must have been authorized through the approve function + * @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 From 2d55234e592a260b0838d49fcaf5eb5d2fd42cb8 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 20:16:53 +0200 Subject: [PATCH 56/89] return boolean to approve and decrease allowance --- assets/eip-7092/ERC7092.sol | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index ffbfdf05d5c94..f65c17e6324de 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -135,26 +135,26 @@ contract ERC7092 is IERC7092, BondStorage { return _approvals[_owner][_spender]; } - function approve(address _spender, uint256 _amount) external { + function approve(address _spender, uint256 _amount) external returns(bool) { address _owner = msg.sender; _approve(_owner, _spender, _amount); } - function approveAll(address _spender) external { + function approveAll(address _spender) external external returns(bool) { address _owner = msg.sender; uint256 _amount = _principals[_owner]; _approve(_owner, _spender, _amount); } - function decreaseAllowance(address _spender, uint256 _amount) external { + function decreaseAllowance(address _spender, uint256 _amount) external returns(bool) { address _owner = msg.sender; _decreaseAllowance(_owner, _spender, _amount); } - function decreaseAllowanceForAll(address _spender) external { + function decreaseAllowanceForAll(address _spender) external returns(bool) { address _owner = msg.sender; uint256 _amount = _principals[_owner]; @@ -208,6 +208,8 @@ contract ERC7092 is IERC7092, BondStorage { _approvals[_owner][_spender] = _approval + _amount; emit Approved(_owner, _spender, _amount); + + return true; } function _decreaseAllowance(address _owner, address _spender, uint256 _amount) internal virtual { @@ -226,6 +228,8 @@ contract ERC7092 is IERC7092, BondStorage { _approvals[_owner][_spender] = _approval - _amount; emit AllowanceDecreased(_owner, _spender, _amount); + + return true; } function _transfer(address _from, address _to, uint256 _amount, bytes calldata _data) internal virtual { From bad0f6c40f22f987707cc5871d59b29645309679 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 20:21:03 +0200 Subject: [PATCH 57/89] Update ERC7092.sol --- assets/eip-7092/ERC7092.sol | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index f65c17e6324de..12f643fdf06c4 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -139,6 +139,8 @@ contract ERC7092 is IERC7092, BondStorage { address _owner = msg.sender; _approve(_owner, _spender, _amount); + + return true; } function approveAll(address _spender) external external returns(bool) { @@ -146,12 +148,16 @@ contract ERC7092 is IERC7092, BondStorage { uint256 _amount = _principals[_owner]; _approve(_owner, _spender, _amount); + + return true; } function decreaseAllowance(address _spender, uint256 _amount) external returns(bool) { address _owner = msg.sender; _decreaseAllowance(_owner, _spender, _amount); + + return true; } function decreaseAllowanceForAll(address _spender) external returns(bool) { @@ -159,12 +165,16 @@ contract ERC7092 is IERC7092, BondStorage { uint256 _amount = _principals[_owner]; _decreaseAllowance(_owner, _spender, _amount); + + return true; } function transfer(address _to, uint256 _amount, bytes calldata _data) external returns(bool) { address _from = msg.sender; _transfer(_from, _to, _amount, _data); + + return true; } function transferAll(address _to, bytes calldata _data) external returns(bool) { @@ -172,6 +182,8 @@ contract ERC7092 is IERC7092, BondStorage { uint256 _amount = _principals[_from]; _transfer(_from, _to, _amount, _data); + + return true; } function transferFrom(address _from, address _to, uint256 _amount, bytes calldata _data) external returns(bool) { @@ -180,6 +192,8 @@ contract ERC7092 is IERC7092, BondStorage { _spendApproval(_from, _spender, _amount); _transfer(_from, _to, _amount, _data); + + return true; } function transferAllFrom(address _from, address _to, bytes calldata _data) external returns(bool) { @@ -189,6 +203,8 @@ contract ERC7092 is IERC7092, BondStorage { _spendApproval(_from, _spender, _amount); _transfer(_from, _to, _amount, _data); + + return true; } function _approve(address _owner, address _spender, uint256 _amount) internal virtual { @@ -208,8 +224,6 @@ contract ERC7092 is IERC7092, BondStorage { _approvals[_owner][_spender] = _approval + _amount; emit Approved(_owner, _spender, _amount); - - return true; } function _decreaseAllowance(address _owner, address _spender, uint256 _amount) internal virtual { @@ -228,8 +242,6 @@ contract ERC7092 is IERC7092, BondStorage { _approvals[_owner][_spender] = _approval - _amount; emit AllowanceDecreased(_owner, _spender, _amount); - - return true; } function _transfer(address _from, address _to, uint256 _amount, bytes calldata _data) internal virtual { @@ -257,8 +269,6 @@ contract ERC7092 is IERC7092, BondStorage { emit Transferred(_from, _to, _amount, _data); _afterBondTransfer(_from, _to, _amount, _data); - - return true; } function _spendApproval(address _from, address _spender, uint256 _amount) internal virtual { From 8c9d9139e9fce925a1b6861f698970f312ae5cef Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 22:54:40 +0200 Subject: [PATCH 58/89] Update Rationale --- EIPS/eip-7092.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index d11345495d296..2469e67ef04b7 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -165,20 +165,20 @@ interface IERC7092 { * @notice Authorizes the `_spender` account to manage all their bonds * @param _spender the address to be authorized by the bondholder */ - function approveAll(address _spender) external; + 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; _amount MUST be a multiple of denomination */ - function decreaseAllowance(address _spender, uint256 _amount) external; + function decreaseAllowance(address _spender, uint256 _amount) external returns(bool); /** * @notice Remove the allowance for `_spender` * @param _spender the address to remove the authorization by from */ - function decreaseAllowanceForAll(address _spender) external; + function decreaseAllowanceForAll(address _spender) external returns(bool); /** * @notice Moves `_amount` bonds to address `_to` @@ -250,11 +250,15 @@ institutional issuance, the smart contracts can be managed by the investment ban 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. -Thge `totalSupply` function is not included since it can be calculated from the `issueVolume` and the bond `denomination`. The `balanceOf` function -used in other standards like [ERC-20](./eip-721) and [ERC-1155](./eip-1155) is not -included since it can be calculated from the tokenholder `principal` and the bond `denomination`. +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 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. + +Another reason that motivates not to extand other standards like the ERC-20 is to allow token tracker 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. -We have added the `data` input in all `transfer` functions to allow the transfer of additional data attached to the bond token. ### Backwards compatibility From 945b65257af104bf2435455fb9b952fde9b4a2f2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 22:56:21 +0200 Subject: [PATCH 59/89] Update --- 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 2469e67ef04b7..ea52ee5f072a5 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -255,7 +255,7 @@ The use of terminology such as `issueVolume` and `principalOf` instead of `total 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. -Another reason that motivates not to extand other standards like the ERC-20 is to allow token tracker platforms like etherscan to represent +Another reason that has motivated not to extand other standards like the ERC-20 is to allow token tracker 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. From ba325e71c90b52c8be4faaeef803a41f3ee4b10a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:08:48 +0200 Subject: [PATCH 60/89] Update eip-7092 --- 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 ea52ee5f072a5..7c70f33b666ca 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -263,7 +263,7 @@ the `denomination`, and the `maturity date`. Those information are very importan ### Backwards compatibility Beacause some functions like `totalSupply` or `balanceOf` are not implemented, the ERC-7092 SHOULD NOT extend existing standards, -like ERC-20 or ERC-1155. The ERC-7092 is a representation of a new token for bonds with all bonds chracateristics +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 chracateristics and functionalities already attached to it. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution From 97ffee7558f2ca1f5b0c480c53be51b093651350 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:23:15 +0200 Subject: [PATCH 61/89] Add optional key --- EIPS/eip-7092.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 7c70f33b666ca..aad75ccbd3a26 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -74,7 +74,7 @@ interface IERC7092 { /** * @notice Returns the numbr 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); @@ -85,6 +85,7 @@ 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); @@ -112,6 +113,7 @@ interface IERC7092 { /** * @notice Returns the coupon type * ex: 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); @@ -164,6 +166,7 @@ interface IERC7092 { /** * @notice Authorizes the `_spender` account to manage all their bonds * @param _spender the address to be authorized by the bondholder + * 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); @@ -177,6 +180,7 @@ interface IERC7092 { /** * @notice Remove the allowance for `_spender` * @param _spender the address to remove the authorization by from + * 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); @@ -192,6 +196,7 @@ interface IERC7092 { * @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 + * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function transferAll(address _to, bytes calldata _data) external returns(bool); @@ -209,6 +214,7 @@ interface IERC7092 { * @param _from the bondholder address * @param _to the address to transfer bonds to * @param _data 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); From dcb36f9628668f489cb36d33ae46f7cc8d2b0fc8 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:25:10 +0200 Subject: [PATCH 62/89] Update eip-7092.md --- EIPS/eip-7092.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index aad75ccbd3a26..8d7ca5e20ac3a 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -85,6 +85,7 @@ 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); @@ -113,6 +114,7 @@ interface IERC7092 { /** * @notice Returns the coupon type * ex: 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); @@ -166,6 +168,7 @@ interface IERC7092 { /** * @notice Authorizes the `_spender` account to manage all their bonds * @param _spender the address to be authorized by the bondholder + * * 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); @@ -180,6 +183,7 @@ interface IERC7092 { /** * @notice Remove the allowance for `_spender` * @param _spender the address to remove the authorization by from + * * 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); @@ -196,6 +200,7 @@ interface IERC7092 { * @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 + * * OPTIONAL - interfaces and other contracts MUST NOT expect these values to be present. The method is used to improve usability. */ function transferAll(address _to, bytes calldata _data) external returns(bool); @@ -214,6 +219,7 @@ interface IERC7092 { * @param _from the bondholder address * @param _to the address to transfer bonds to * @param _data 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); From a893fdc91ad79845cc2ae65902314421e838fdb5 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:42:07 +0200 Subject: [PATCH 63/89] Update eip-7092.md --- EIPS/eip-7092.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 8d7ca5e20ac3a..b1b38c658efaa 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -68,6 +68,8 @@ 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` */ function symbol() external view returns(string memory); @@ -121,6 +123,8 @@ 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. */ function couponFrequency() external view returns(uint256); @@ -138,6 +142,8 @@ interface IERC7092 { /** * @notice Returns the day count basis * Ex: 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); From 2563f2cda19ad47230be5a8a0f837826220068b1 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:44:43 +0200 Subject: [PATCH 64/89] Update eip-7092.md --- 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 b1b38c658efaa..637a61bc1675e 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -68,8 +68,8 @@ 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` + * 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); From ef19d49dfb0bba47a93b61410af9134383feff33 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:46:39 +0200 Subject: [PATCH 65/89] Update eip-7092.md --- EIPS/eip-7092.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 637a61bc1675e..bdc65d5122b42 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -70,6 +70,8 @@ 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 49628deca42aaf2f8a70bf242c5ece53523441a9 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:55:58 +0200 Subject: [PATCH 66/89] Update eip-7092.md --- 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 bdc65d5122b42..757a16d160ca4 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -280,7 +280,7 @@ the ERC-7092 token not as a simple ERC-20 token, but as a new token showing some the `denomination`, and the `maturity date`. Those information are very important for bondholders to know the return on the capital invested. -### Backwards compatibility +## Backwards compatibility 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 chracateristics From 083dcf7d2577fbc0e69b0d182309f1015db9234d Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:59:07 +0200 Subject: [PATCH 67/89] Update eip-7092.md --- 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 757a16d160ca4..bdc65d5122b42 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -280,7 +280,7 @@ the ERC-7092 token not as a simple ERC-20 token, but as a new token showing some the `denomination`, and the `maturity date`. Those information are very important for bondholders to know the return on the capital invested. -## Backwards compatibility +### Backwards compatibility 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 chracateristics From 802d3410af7ec000bf015b612e157181ab4fbdf2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 17 Jul 2023 19:11:31 +0200 Subject: [PATCH 68/89] Update ERC7092.sol --- assets/eip-7092/ERC7092.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index 12f643fdf06c4..7228e79def0ff 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -38,7 +38,7 @@ contract ERC7092 is IERC7092, BondStorage { uint256 _denomination = _bondInfo.denomination; require(investor != address(0), "ERC7092: ZERO_ADDRESS_INVESTOR"); - require(principal != 0 && principal % _denomination == 0, "ERC: INVALID_PRINCIPAL_AMOUNT"); + require(principal != 0 && (principal * _denomination) % _denomination == 0, "ERC: INVALID_PRINCIPAL_AMOUNT"); volume += principal; _principals[investor] = principal; From 71e3f1166372f01cb2ea6404632a18dd8d2cd022 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 03:37:46 +0200 Subject: [PATCH 69/89] Update eip-7092.md --- EIPS/eip-7092.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index bdc65d5122b42..2e729f4621f46 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -101,10 +101,11 @@ interface IERC7092 { 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 (total debt amount). It is RECOMMENDED to express the issue volume in 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 - * NOTICE: The `issue volume` in denomination unit MUST be equal to the `totalSupply` of the bonds, i.e. the total number of bond tokens issued. */ function issueVolume() external view returns(uint256); @@ -150,10 +151,10 @@ interface IERC7092 { 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: The `principal` in denomination unit MUST be equal to the `balance` of an account, i.e. the number of bond tokens owned by an account. + * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in 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 * @param _account account address */ function principalOf(address _account) external view returns(uint256); @@ -271,14 +272,29 @@ 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 terminology as with traditional bonds. Furthermore, by adding the `data` input parameter +[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 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. -Another reason that has motivated not to extand other standards like the ERC-20 is to allow token tracker platforms like etherscan to represent +Another reason that has motivated not to extend other standards like the ERC-20 is to allow token tracker 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. +### 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`. + +`totalSupply = issueVolume / denomination` + +### Account Balance + +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`. + +`balanceOf(account) = principalOf(account) / denomination` ### Backwards compatibility From 6d0bb7592439121134c8cacb22ace3a385d50d5e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 03:39:53 +0200 Subject: [PATCH 70/89] Update eip-7092.md --- EIPS/eip-7092.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index 2e729f4621f46..9c7cad11d8068 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -286,7 +286,9 @@ We made the choice not to define the `totalSupply` function beacause it can be d 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`. -`totalSupply = issueVolume / denomination` +```javascript + totalSupply = issueVolume / denomination +``` ### Account Balance @@ -294,7 +296,9 @@ Because the balance of an account can be derived from both the `principal` and t 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`. -`balanceOf(account) = principalOf(account) / denomination` +```javascript + balanceOf(account) = principalOf(account) / denomination +``` ### Backwards compatibility From 7cba929d13a595c945fa580119f721026ba4d161 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 03:41:52 +0200 Subject: [PATCH 71/89] Update eip-7092.md --- 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 9c7cad11d8068..52981876d21e9 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -101,7 +101,7 @@ interface IERC7092 { function denomination() external view returns(uint256); /** - * @notice Returns the issue volume (total debt amount). It is RECOMMENDED to express the issue volume in bond currency unit (USDC, DAI, etc...). + * @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 @@ -151,7 +151,7 @@ interface IERC7092 { function dayCountBasis() external view returns(uint256); /** - * @notice Returns the principal of an account. It is RECOMMENDED to express the principal in 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 (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 From 6fffe5897697f59ef6aacd68b607fa19d2826e5d Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:21:27 +0200 Subject: [PATCH 72/89] add totalSupply and balanceOf in BondStorage --- assets/eip-7092/BondStorage.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index 045fa941f61dd..6a3f439e6ee62 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -38,10 +38,12 @@ contract BondStorage { enum BondStatus {UNREGISTERED, SUBMITTED, ISSUED, REDEEMED} mapping(string => Bond) internal _bond; + mapping(address => uint256) public balanceOf; mapping(string => Issuer) internal _issuer; mapping(address => uint256) internal _principals; mapping(address => mapping(address => uint256)) internal _approvals; + uint256 public totalSupply; string internal bondISIN; string internal _countryOfIssuance; From 4c22f16d13af6651ae8bdf9b90f5665d365d81e4 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:34:42 +0200 Subject: [PATCH 73/89] add totalSupply and balanceOf functions --- assets/eip-7092/ERC7092.sol | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index 7228e79def0ff..bdf1b1e2cf1ef 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -131,6 +131,18 @@ contract ERC7092 is IERC7092, BondStorage { 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; + } + function approval(address _owner, address _spender) external view returns(uint256) { return _approvals[_owner][_spender]; } From 63eeb8e8d20a7410e9b799c7900b10ab21e9f4f6 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:36:18 +0200 Subject: [PATCH 74/89] add totalSupply and balanceOf functions --- assets/eip-7092/ERC7092.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index bdf1b1e2cf1ef..ceb7ebe59e726 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -132,13 +132,13 @@ contract ERC7092 is IERC7092, BondStorage { } function balanceOf(address _account) public view returns(uint256) { - require(_bondStatus = BondStatus.ISSUED, "ERC7092: NOT_ISSUED_OR_REDEEMED"); + 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"); + require(_bondStatus == BondStatus.ISSUED, "ERC7092: NOT_ISSUED_OR_REDEEMED"); return _bond[bondISIN].issueVolume / _bond[bondISIN].denomination; } From a68c650385abc1744cfa2f7c6c176ae83b267a7a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:38:29 +0200 Subject: [PATCH 75/89] remove totalSupply and balanceOf in bondStorage - already defined in ERC contract --- 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 6a3f439e6ee62..045fa941f61dd 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -38,12 +38,10 @@ contract BondStorage { enum BondStatus {UNREGISTERED, SUBMITTED, ISSUED, REDEEMED} mapping(string => Bond) internal _bond; - mapping(address => uint256) public balanceOf; mapping(string => Issuer) internal _issuer; mapping(address => uint256) internal _principals; mapping(address => mapping(address => uint256)) internal _approvals; - uint256 public totalSupply; string internal bondISIN; string internal _countryOfIssuance; From 7d9f137c174b0cf5e880cfaff2809a8bfbc8f197 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Fri, 21 Jul 2023 12:01:14 +0200 Subject: [PATCH 76/89] Update eip-7092.md --- 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 52981876d21e9..46e092e62b4a2 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -303,7 +303,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha ### Backwards compatibility 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 chracateristics +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. **_For the reasons mentionned above, we recommand a pure implementation of the standard_** to issue tokenized bonds, since any hybrid solution From af75721ad70d9e56fdd3f2b1b9ffa483306b446e Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Sun, 23 Jul 2023 15:35:47 +0200 Subject: [PATCH 77/89] Update CouponMath.sol --- assets/eip-7092/coupons/CouponMath.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/eip-7092/coupons/CouponMath.sol b/assets/eip-7092/coupons/CouponMath.sol index 9f8eaeb74dbe7..5d39fa873c2b0 100644 --- a/assets/eip-7092/coupons/CouponMath.sol +++ b/assets/eip-7092/coupons/CouponMath.sol @@ -31,12 +31,12 @@ library CouponMath { address _bondContract ) external view returns(uint256) { uint256 couponRate = IERC7092(_bondContract).couponRate(); - uint256 couponDenomination = IERC7092(_bondContract).denomination(); + uint256 denomination = IERC7092(_bondContract).denomination(); uint256 principal = IERC7092(_bondContract).principalOf(_investor); uint256 frequency = IERC7092(_bondContract).couponFrequency(); uint256 numberOfDays = _numberOfDays(_bondContract); - return principal * couponDenomination * couponRate * _duration / (frequency * numberOfDays); + return principal * denomination * couponRate * _duration / (frequency * numberOfDays); } /** From 2e6418cb048b1b9a0005b8a99e5b97e46517396a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:16:24 +0200 Subject: [PATCH 78/89] update text: replace tracker by explorer --- 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 46e092e62b4a2..aaface302f500 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -276,7 +276,7 @@ The use of terminology such as `issueVolume` and `principalOf` instead of `total 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. -Another reason that has motivated not to extend other standards like the ERC-20 is to allow token tracker platforms like etherscan to represent +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. From 6250c34cf6bf5f14d5c4935ed23c390bf85ac60b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:18:33 +0200 Subject: [PATCH 79/89] add link to etherscan --- 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 aaface302f500..bcd789137aebd 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -276,7 +276,7 @@ The use of terminology such as `issueVolume` and `principalOf` instead of `total 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. -Another reason that has motivated not to extend other standards like the ERC-20 is to allow token explorer platforms like etherscan to represent +Another reason that has motivated not to extend other standards like the ERC-20 is to allow token explorer platforms like [etherscan](https://etherscan.io) 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. From 54c6200bfa459d86c05cf3fce0c6675f998fa84b Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:20:28 +0200 Subject: [PATCH 80/89] remove link: not supported --- 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 bcd789137aebd..aaface302f500 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -276,7 +276,7 @@ The use of terminology such as `issueVolume` and `principalOf` instead of `total 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. -Another reason that has motivated not to extend other standards like the ERC-20 is to allow token explorer platforms like [etherscan](https://etherscan.io) to represent +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. From aeb7991beb019f4d4af2cfa1841b90ece7aea668 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 01:59:20 +0200 Subject: [PATCH 81/89] update the eip-7092 according to comments from @lightclient --- EIPS/eip-7092.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-7092.md b/EIPS/eip-7092.md index aaface302f500..1f5d0396ab97f 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -1,7 +1,7 @@ --- eip: 7092 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. +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 @@ -12,14 +12,14 @@ created: 2023-05-28 ## Abstract -This proposal introduces fixed income financial bonds. Important bonds characteristics such as the International Securities Identification Number (ISIN), +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. ## Motivation -Fixed income instruments are one of the asset classes that is widely used by corporations and other entities to raise funds. Bonds +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. @@ -62,7 +62,7 @@ interface IERC7092 { function isin() external view returns(string memory); /** - * @notice Returs the bond name + * @notice Returns the bond name */ function name() external view returns(string memory); @@ -76,7 +76,7 @@ interface IERC7092 { function symbol() external view returns(string memory); /** - * @notice Returns the numbr of decimals the bond uses - e?g `10`, means to divide the token amount by `10000000000` + * @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. */ @@ -300,7 +300,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha balanceOf(account) = principalOf(account) / denomination ``` -### Backwards compatibility +## Backwards compatibility 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 From 5967954d310fe0953a57389fdb07636e6b5b51bc Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 02:05:46 +0200 Subject: [PATCH 82/89] keep backward compatibility as sub-sub-section for tests to pass --- 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 1f5d0396ab97f..084ec408ca7ef 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -300,7 +300,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha balanceOf(account) = principalOf(account) / denomination ``` -## Backwards compatibility +### Backwards compatibility 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 From 62358ad41b9cac96a772021e598e7020fc8ec2f2 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:00:19 +0200 Subject: [PATCH 83/89] Update EIPS/eip-7092.md Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- 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 084ec408ca7ef..1f5d0396ab97f 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -300,7 +300,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha balanceOf(account) = principalOf(account) / denomination ``` -### Backwards compatibility +## Backwards compatibility 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 From ca61a310e5a7a9ba769f0bc73327b8e72e4e1f03 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:06:10 +0200 Subject: [PATCH 84/89] Update eip-7092.md --- 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 1f5d0396ab97f..084ec408ca7ef 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -300,7 +300,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha balanceOf(account) = principalOf(account) / denomination ``` -## Backwards compatibility +### Backwards compatibility 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 From c18b8d6deb405ad3dfb7d740fc75acdace63fde0 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:14:37 +0200 Subject: [PATCH 85/89] UIpdarte the Backward Compatibility to appear as a section --- 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 084ec408ca7ef..6971b21604b79 100644 --- a/EIPS/eip-7092.md +++ b/EIPS/eip-7092.md @@ -300,7 +300,7 @@ the `balance` of an account MUST be equal to the ratio of the `principal` of tha balanceOf(account) = principalOf(account) / denomination ``` -### Backwards compatibility +## Backwards Compatibility 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 From 053c39148d27f8b7af4f4fbe20adf3797937ad57 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:09:45 +0200 Subject: [PATCH 86/89] Update assets/eip-7092/IERC7092.sol Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- assets/eip-7092/IERC7092.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/eip-7092/IERC7092.sol b/assets/eip-7092/IERC7092.sol index b4dbeca06c6a3..bae6f376f8873 100644 --- a/assets/eip-7092/IERC7092.sol +++ b/assets/eip-7092/IERC7092.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; /** From b7e8fd02561c4b7b157330c3c5e28f797cb39401 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:09:59 +0200 Subject: [PATCH 87/89] Update assets/eip-7092/ERC7092.sol Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- assets/eip-7092/ERC7092.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/eip-7092/ERC7092.sol b/assets/eip-7092/ERC7092.sol index ceb7ebe59e726..cf410ed8edb7c 100644 --- a/assets/eip-7092/ERC7092.sol +++ b/assets/eip-7092/ERC7092.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; import "./IERC7092.sol"; From 420b0c80399118acd477b69aad56f9206f5e6a3a Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:10:05 +0200 Subject: [PATCH 88/89] Update assets/eip-7092/BondStorage.sol Co-authored-by: lightclient <14004106+lightclient@users.noreply.github.com> --- assets/eip-7092/BondStorage.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/eip-7092/BondStorage.sol b/assets/eip-7092/BondStorage.sol index 045fa941f61dd..d68928ac5ed63 100644 --- a/assets/eip-7092/BondStorage.sol +++ b/assets/eip-7092/BondStorage.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.18; contract BondStorage { From 0984d88432e2fabbf445ea39a57cbbde51f54224 Mon Sep 17 00:00:00 2001 From: sam say <80607135+Edoumou@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:11:21 +0200 Subject: [PATCH 89/89] Update CouponMath.sol --- assets/eip-7092/coupons/CouponMath.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/eip-7092/coupons/CouponMath.sol b/assets/eip-7092/coupons/CouponMath.sol index 5d39fa873c2b0..458b42d5d2c91 100644 --- a/assets/eip-7092/coupons/CouponMath.sol +++ b/assets/eip-7092/coupons/CouponMath.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; import "../IERC7092.sol";