OpenZeppelin / openzeppelin-contracts

OpenZeppelin Contracts is a library for secure smart contract development.
https://openzeppelin.com/contracts
MIT License
24.82k stars 11.78k forks source link

ERC20Vesting: vesting functionality for ERC20 tokens #4441

Open Keref opened 1 year ago

Keref commented 1 year ago

šŸ§ Motivation Escrowed tokens are omnipresent in DeFi, as governance, airdrops and liquidity mining use vesting to control dumping. I suggest adding an ERC20Vesting extension that easily allows vesting tokens.

šŸ“ Details

Vesting can be used in particular in combination with ERC20Wrapper. The vesting schedule is linear by default but can be overriden (we use some exponential for our own vesting schedule). The logic when withdrawing isn't fixed: the extension returns the amount already vested and the amount remaining, up to the implementation to choose whether to allow early unlock and which penalty to apply.

I think it would make sense to add some additional virtual function to handle the data field, or to modify a schedule (eg, to allow partial withdrawal). The function names differ from VestingWallet, maybe it would make sense to harmonize those. Please give me feedback!

Draft implementation: https://github.com/Keref/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Vesting.sol

Amxx commented 1 year ago

Hello @Keref

Are you familiar with our VestingWallet ? Can you tell us more about the usecases where it does not work for you ?

My first thought is that the vesting should be handled by a dedicated contract, and not by the token itself.

Keref commented 1 year ago

Hi, yes I'm aware. The vesting wallet is created to vest for 1 unique beneficiary provided in the constructor. This makes it only usable for initial distribution of tokens for, say, a VC who bought tokens early.

What I'm proposing is an ERC20 extension that can be added to any token. It can be used to escrow governance tokens, in my case the esToken allows depositing Token, also extends a number of governance functions, and uses ERC20Vesting (we prefer vesting rather than the ve- model).

frangio commented 1 year ago

The linked contract says its an extension of ERC20 but the contract doesn't extend ERC20 in any way. Can you clarify how the interaction is supposed to work with ERC20 balances?

Keref commented 1 year ago

Indeed good feedback, the balance verification was in my mock contract. I changed ERC20Vesting to extend ERC20, and add some vesting function with balance check.

A simple use case would be to extend ERC20Wrapper and ERC20Vesting, and to only allow withdrawal of vesting tokens (e.g only if vesting is over, or could burn the remaining like Radiant Protocol does).

In our case, our esToken extends ERC20Wrapper, ERC20Vesting, ERC20Votes, and tokens can be deposited for governance and rewards, with a 3 months unlock period (code isn't open source but will be soon, can share the link here when it is).

It can also extend a masterchef-like contract so that withdrawal takes 1 week.

frangio commented 1 year ago

Are the tokens under vesting supposed to be transferable?

We need a clear description of what the feature is supposed to be so we can evaluate if it's a right fit for the library. If there is something like this out there please share the reference.

Keref commented 1 year ago

Here's an attempt to clarify all: ERC20Vesting is an ERC20 extension that allows controlling token flows through vesting. Vesting unlocks one or more functions (withdrawal, transfer, mint...)

Functionalities:

Example use cases:

I added some mock contracts for each example use case EsGovernanceTokenMock, VeGovernanceTokenMock, VestedMiningRewardsMock to showcase how to use and why this is useful as a general extension to include in OpenZeppelin. For example a ve- lockup model can then be implemented with less than 30 lines of code. Thanks for your feedback! šŸ™

Edit: btw there aren't test files because for our project we use Brownie tests, so I'd rather not duplicate unless there's actual interest in integrating ERC20Vesting in OpenZeppelin

frangio commented 1 year ago

Great, thank you. We will leave this open for consideration.

TrejGun commented 1 year ago

As the whole US economy is based on debts it makes sense to include functions for changing vesting owners. Unfortunately this contract does not have such functionality. OZ VestingWallet has such functionality when is extended from Ownable. But the easiest way to transfer ownership would be NFT with vesting because it would be easy to trade on any marketplace

Rickcodes21 commented 11 months ago

Cross-chain swaps, also known as atomic swaps or cross-chain atomic swaps, are a mechanism that allows the exchange of one cryptocurrency directly for another between two different blockchain networks without the need for an intermediary, such as a centralized exchange. These swaps are secure, trustless, and decentralized, making them an attractive solution for interoperability between blockchain ecosystems. Hereā€™s how cross-chain swaps work:

1.  Participants:
ā€¢   Cross-chain swaps involve at least two participants, each using a different blockchain network. For simplicity, letā€™s call them Alice and Bob.
2.  Agreement:
ā€¢   Alice and Bob agree to swap cryptocurrencies. They specify the amount to be exchanged, the exchange rate, and the duration of the swap (a predefined time window during which the swap can occur).
3.  Hash Time-Locked Contracts (HTLCs):
ā€¢   Alice and Bob both create Hash Time-Locked Contracts (HTLCs) on their respective blockchain networks. These smart contracts lock up the funds being exchanged.
ā€¢   HTLCs consist of two key components: a cryptographic hash of a secret and a time lock.
4.  Secret Generation:
ā€¢   Alice generates a random secret and hashes it to create a cryptographic hash (Hash1). She shares Hash1 with Bob but keeps the secret itself secret.
5.  Swap Initiation:
ā€¢   Alice initiates the swap by revealing Hash1 and the time lock to Bob. Bob can then verify the information on Aliceā€™s blockchain.
6.  Bobā€™s Participation:
ā€¢   Bob, seeing that Alice has revealed Hash1 and the time lock, creates a second cryptographic hash (Hash2) using the same secret but does not reveal the secret itself.
ā€¢   He initiates a similar HTLC on his blockchain, using Hash2 and the same time lock as Aliceā€™s HTLC.
7.  Execution:
ā€¢   Once both HTLCs are in place and the time lock has not expired, Alice and Bob can claim the funds in each otherā€™s HTLCs by revealing the secret they know.
ā€¢   Alice reveals the secret to claim Bobā€™s funds on Bobā€™s blockchain, and Bob does the same to claim Aliceā€™s funds on Aliceā€™s blockchain.
ā€¢   This reveals the secret on both blockchains, ensuring that both participants receive the cryptocurrency they agreed to swap.
8.  Completion:
ā€¢   The swap is considered complete when both participants have successfully claimed the funds from each otherā€™s HTLCs.
ā€¢   If either party fails to claim the funds within the specified time lock period, the funds are returned to their original owners.
9.  Trustlessness and Security:
ā€¢   Cross-chain swaps are trustless because neither party can access the otherā€™s funds without revealing the secret, and thereā€™s no need for a trusted intermediary.
ā€¢   The security of cross-chain swaps relies on cryptographic principles and the predetermined rules of the HTLCs.