EIP(BEP)-659 Multiple Callable Bonds Standard Proposal draft

Sigma Protocol
Mar 13 · 12 min read

See the proposal on EIP s official website

Simple Summary

A standard interface for contract, that manage multiple callable bonds. A single contract includes any given number of bond classes, bond nonce, bond balance of an address. This standard provides independent functions to read, transfer any collection of bonds, as well as allow bonds to be redeemed from the bond issuer if certain conditions are met. This token standard can replace current ERC20 LP token. ERC-659 has more complex data structure, which will allow the LP token to store more information, and allow the developer to build more sophisticated logic for the redemption and reward system of the DEFI project in question.

Abstract

This API standard allows for the creation of any number of bonds type in a single contract. Existing LP token standards like ERC-20 require deployment of separate factory and token contracts per token type. The need of issuing bonds with multiple redemption data can’t be achieved with existing token standards. ERC-659 Multiple Callable Bonds Standard allows for each bond class ID to represent a new configurable token type, and for each bond nonce to represent an issuing date or any other forms of data in uint256. Every single nonce of a bond class may have its own metadata, supply and other redemption conditions.

Motivation

Current LP token is a simple ERC-20 token, which has not much complicity in data structure. To allow more complex reward and redemption logic to be built, we need a new LP token standard that can manage multiple bonds, stores much more data and gas efficient. ERC-659 standard interface allows any tokens on solidity compatible block chains to create its own bond. These bonds with the same interface standard can be exchanged in secondary market. And it allows any 3rd party wallet applications or exchanges to read the balance and the redemption conditions of these tokens. ERC-659 bonds can also be packed into separate packages. Those packages can in their turn be divided and exchanged in a secondary market.

New functions built in ERC-659 Multiple Callable Bonds Standard, will allow the users to economize their gas fee spend. Trading and burning of ERC-659 Bonds will also multiply tokens market cap, helping it to recover from recession period(1). Existing structures, such as AMM exchanges or lending platform can be updated to recognize ERC-659 Bonds.

Specification

totalSupply()**

"totalSupply()" allows anyone to read the total supply of a given class nonce and bond nonce, this include burned and redeemed Supply

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the active supply of the bond in question. — e.g. "5821200000000".

activeSupply()

"activeSupply()" allows anyone to read the non-burned and non-redeemed Supply of a given class nonce and bond nonce.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the active supply of the bond in question. — e.g. "5821200000000".

burnedSupply()

"burnedSupply()" allows anyone to read the redeemed Supply of a given class and bond nonce.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the active supply of the bond in question. — e.g. "612300000000".

redeemedSupply**()**

"redeemedSupply()" allows anyone to read the redeemed Supply of a given class and bond nonce.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the active supply of the bond in question. — e.g. "612300000000".

balanceOf()

"balanceOf()" allows anyone to read the remaining balance of an address. This will only return the balance of a single bond class and bond date nonce.

The "account" is the address of the token holder.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the balance of the giving bond class and bond nonce. — e.g. "571300000000".

getBondSymbol()

"getBondSymbol()" allows anyone to read the symbol of a bond class.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the symbol string of the bond class. — e.g. bond symbol="SASH-BUSD bond".**SASH as the first half of the bond symbol represents the settlement token of the bond. BUSD as the second half of the bond symbol represents the token used for the perches of this bond. If the bond have more than one settlement token or buying token, the symbol should be "Token1,Token2-Token3,Token4 bond"

getBondInfo()

"getBondInfo()" allows anyone to read the information of a bond nonce.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns the bond symbol and a list of uint256 parameters of a bond nonce. — e.g. ["SASH-BUSD","1615584000",(3rd uint256)...].*** Every bond contract can have their own list. But the first uint256 in the list MUST be the UTC time code of the issuing time.*

bondIsRedeemable()

"bondIsRedeemble()" allows anyone to check if a bond is redeemable.*** the conditions of redemption can be speechified with one or several internal functions.*

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the nonce of the bond. This param is for distinctions of the issuing conditions of the bond.

Returns "true" if the cited bond is redeemable. and "false"if is not.

issueBond()

"issueBond()" allows issuing any number of bond types to an address.

The calling of this function needs to be restricted to bond issuer contract.

The "_to" is the address to which the bond will be issued.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "_amount" is the amount of the bond, that "_to" address will receive.

e.g.

those input mean“ issuing to wallet address, 1000of bond class 0.” Returns a bool.

"true" if the bond are issued. and "false"if are not.

redeemBond()

"redeemBond()" allows redemption of any number of bond types from an address.

The calling of this function needs to be restricted to bond issuer contract.

The "_from" is the address from which the bond will be redeemed.

The "class" is the class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the list of nonce of the given bond class. This param is for distinctions of the issuing conditions of the bond.

The "_amount" is the list of amount of the bond, that "_from" address will redeem.

e.g.

those input mean “redeem from wallet address(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef), 500000000 of bond class1 nonce 42, 60000000 of bond class2 nonce 61, 150000000 of bond class3 nonce 25.

Returns a bool

"true" if the bond are redeemed and "false"if are not.

transferBond()

"transferBond()" allows the transfer of any number of bond types from an address to another.

The"_from" argument is the address of the holder whose balance about to decrees.

The "_to" argument is the address of the recipient whose balance is about to increased.

The "class" is the list of class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the list of nonce of the given bond class. This param is for distinctions of the issuing conditions of the bond.

The "_amount" is the list of amount of the bond, that will be transferred from "_from"address to "_to" address.

e.g.

those input mean “ transfer, from "_from" address, to "_to" address, 500000000 of bond class1 nonce 42, 60000000 of bond class2 nonce 61, 150000000 of bond class3 nonce 25.

Returns a bool.

"true"if passed.

**If one transaction in the group is failed the function will revert all passed transactions. *

burnBond()

"burnBond()" allows the transfer of any number of bond types from an address to another.

The"_from" argument is the address of the holder whose balance about to decrees.

The "class" is the list of class nonce of bond, the first bond class created will be 0, and so on.

The "nonce" is the list of nonce of the given bond class. This param is for distinctions of the issuing conditions of the bond.

The "_amount" is the list of amount of the bond, that will be transferred from "_from"address to "_to" address.

e.g.

those input mean “ burn, from "_from" address, to "_to" address, 500000000 of bond class1 nonce 42, 60000000 of bond class2 nonce 61, 150000000 of bond class3 nonce 25.

Returns a bool.

"true"if passed.

**If one transaction in the group is failed the function will revert all passed transactions. *

Data structure

"_balances"Is the mapping from bond class and nonce to account balances.

4D array of address => (bond class => (bond nonce => bond balances)).

e.g.

0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef =>(1 =>(5 => 500000000)); this example gives the balance of: address 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef possess 500000000 of bond class 1, bond nonce 5.

"_totalSupply"Is the mapping from bond class and nonce to the total active supply.

**total supply = total supply +burned supply +redeemed supply.

3D array of bond class => (bond nonce => bond total supply).

e.g.

1 =>(5 => 25000000000); this example gives the total supply of: bond class 1, bond nonce 5 has a total supply of 25000000000 .

“_activeSupply”`Is the mapping from bond class and nonce to the total active supply.

**Active supply = total supply — burned supply — redeemed supply.

3D array of bond class => (bond nonce => bond active supply).

e.g.

1 =>(5 => 25000000000); this example gives the total active supply of: bond class 1, bond nonce 5 has a total active supply of 25000000000 .

"_burnedSupply"Is the mapping from bond class and nonce to the total burned supply.

**Burned supply = total supply — active supply — redeemed supply.

3D array of bond class => (bond nonce => bond burned supply).

e.g.

1 =>(5 => 0); this example gives the total burned supply of: bond class 1, bond nonce 5 has a total burned supply of 0 .

"_redeemedSupply"Is the mapping from bond class and nonce to the total active supply.

*** redeemed supply = total supply — active supply — burned supply.*

3D array of bond class => (bond nonce => bond redeemed supply).

e.g.

1 =>(5 => 5000000000); this example gives the total redeemed supply of: bond class 1, bond nonce 5 has a total redeemed supply of 5000000000 .

"_Symbol"Is the mapping from bond class to a string of bond symbol.

2D array of bond class => bond symbol.

e.g.

**bond symbol="SASH-BUSD bond".**SASH as the first half of the bond symbol represents the settlement token of the bond. BUSD as the second half of the bond symbol represents the token used for the perches of this bond. If the bond have more than one settlement token or buying token, the symbol should be "Token1,Token2-Token3,Token4 bond"

"_info"Is the mapping from bond class and nonce to a string list of uint256.

3D array of bond class => (bond nonce => bond info).

in this list, [(bond symbol), (timestamp),(3rd string)]

e.g. ["1615584000",(2nd uint256)...]

**This function allows the return of a list of uint256. every bond contract can have their own list. But the first string in the list MUST be the UTC time code of the issuing time,

**bond symbol="SASH-BUSD bond".**SASH as the first half of the bond symbol represents the settlement token of the bond. BUSD as the second half of the bond symbol represents the token used for the perches of this bond. If the bond have more than one settlement token or buying token, the symbol should be "Token1,Token2-Token3,Token4 bond"

EVENT

"eventIssueBond" MUST trigger when Bonds are issued. This SHOULD not include zero value Issuing.

e.g.

"issue by address(operator) 500 SASH-USD Bond(Nonce14) to 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef"

"eventRedeemBond" MUST trigger when Bonds are redeemed. This SHOULD not include zero value redemption. When burn a bond MUST not create this event(Use"eventBurnBond" instead).

e.g.

"redeem by address(_operator) 500 SASH-USD Bond(Nonce14) to 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef"

"eventBurnBond" MUST trigger when Bonds are burned. This SHOULD not include zero value burning. When redeem a bond MUST not create this event(Use"event redeemBond" instead).

e.g.

"burn by address(_operator) 500 SASH-USD Bond(Nonce14) from 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef"

"eventTransferBond" MUST trigger when Bonds are transferred. This SHOULD not include zero value transfers. Transfer event with the _from 0x0 MUST not create this event(Use"event issueBond" instead ). Transfer event with the _to 0x0 MUST not create this event(Use"event redeemBond" when redemption, and "event burnBond" when burning).

e.g.

"transfer by address(_operator) 500 SASH-USD Bond(Nonce14) from 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, to address(_to)"

Backwards Compatibility

ERC-659 contract is not Compatible with contracts that don’t have an ERC-659 interface built in. This requires the existing contract to upgrade with ERC-659 interface. The receiving of ERC-659 Bond need the implementation of ERC659 interface in the receiver contract.

However any existing ERC-20 token contract can issue their ERC-659 bond, by giving the minting role to a bonk contract with ERC-659 interface built in. The implementation of This can be found in our Use Cases.

To ensure the reading of transactions, "eventIssueBond" ,"eventRedeemBond" ,"eventBurnBond" ,"eventTransferBond", Events cited above MUST be emitted when such transaction is passed.

Note that the ERC 659 interface is also compatible with ERC-20 and ERC-721 interface . But the creation of a separated bank contract is recommended for reading and future upgrade needs and .

The issuing of ERC-659 bonds is not limited to ERC-20 token. Standard like ERC-721 nonfungible token can also issue their bond with the help of ERC-659 interface.

Any ERC659 bond or any hybrid of ERC-20 and ERC-721 contract can be used as the collateral for another ERC-659 bond. This allows the market to create bond represent no longer a single type of ERC-20 token. Bond can now represent a collection of collaterals in ERC-20 token, ERC-721 nonfungible token and ERC-659 Multiple callable bonds…

Use Cases

https://github.com/sgmfinance/erc-659

**This demonstration show only a simple application of ERC659 Multiple Callable Bonds Standard. Developers can build much sophisticated logic with this interface. No function used in the example serves as a guild-line.

Reference

https://eips.ethereum.org/EIPS/eip-20

https://eips.ethereum.org/EIPS/eip-721

Security Considerations

There are no known security considerations for this EIP. More security considerations will be added after the authoring/feedback process of this EIP.

Copyright

License

apache 2.0

Website: https://sgm.finance/

Twitter: https://twitter.com/ProtocolSigma

Medium: https://medium.com/@sigma_protocol

Telegram: https://t.me/sigma_protocol

Github: https://github.com/sgmfinance/erc-659

Brief introduction of Sigma Protocol:

https://sigma-protocol.medium.com/introducing-sigma-protocol-a-bond-based-decentralized-monetary-model-626801006af0

The Future of algorithmic stablecoins:

https://medium.com/coinmonks/the-future-of-algorithmic-stable-coin-13ddbc27485

Coinmonks

Coinmonks is a non-profit Crypto educational publication.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store