# Overview
This issue aims at discussing RC0 Token Proposal ([[1](https://sna…pshot.org/#/keepstakers.eth/proposal/QmV9o1AiZSVZ5fdKJXYmGTcnYQodP8h1gWt9EEMaNFXsDs)], [[2](https://snapshot.org/#/nudao.eth/proposal/QmdH23qw5A1Afr3gT6qokn18UskpunM1cnzZpABsJtxEAv)]) implementation and how KEEP and NU holders will move their positions to T. Solutions proposed in this issue should be generic enough so that they can be easily integrated with existing contracts of Keep Network and NuCypher.
# Roles in the system
We identified 3 roles in the system essential to the migration. There are multiple variants of these roles but it is expected that understanding and implementing paths for 3 basic roles is enough and all their variants can be handled by the basic migration paths for these roles.
The roles are:
- liquid token owner,
- grantee,
- staker.
# T token
We will implement T ERC20 token based on the audited [`ERC20WithPermit`](https://github.com/keep-network/tbtc-v2/blob/main/solidity/contracts/token/ERC20WithPermit.sol) used for TBTC v2 and Coverage Pool COV token. It is a burnable ERC20 token with EIP2612 permit functionality. Users can authorize a transfer of their tokens with a signature conforming EIP712 standard instead of an on-chain transaction from their address. Anyone can submit this signature on the user's behalf by calling the permit function, as specified in EIP2612 standard, paying gas fees, and possibly performing other actions in the same transaction.
# KEEP/NU <> T migration for liquid token owners and grantees
Liquid token owners will be able to migrate their entire positions right away. Grantees will have to gradually migrate their positions by releasing vested tokens into liquid ones and migrating them the same way as liquid token owners. Keep in mind grant is a promise of tokens. One cannot wrap tokens they have promised and do not own yet. Still, they will be able to stake their KEEP/NU to earn in T network according to their existing staking policy.
We will implement a Vending Machine smart contract, similar to the one we use for [TBTC v1 <> TBTC v2 minting](https://github.com/keep-network/tbtc-v2/pull/9). There will be two instances of this contract deployed. One for KEEP<>T and another for NU<>T. The existing Vending Machine smart contract will require two modifications:
- there has to be a `mapping address → uint256` tracking the amounts minted/unminted per account so that only selected accounts can unmint, up to the amount they previously minted,
- we need to introduce a ratio for wrapping/unwrapping as this will not be a 1:1 transformation.
Upon deploying T contract with 10 billion supply:
- 45% will be transferred to KEEP<>T vending machine,
- 45% will be transferred to NU<>T vending machine,
- 10% will be transferred to the DAO,
- T token ownership will be transferred to the DAO so that it can control the inflation and mint tokens.
Additionally, it has to be decided if the DAO can burn tokens it does not own. That’s the current assumption for token owner role in our `ERC20WithPermit` implementation. Most probably, this has to be revisited to allow DAO to mint tokens and burn only the tokens it does have on its balance.
# KEEP<>T migration for staked tokens
Token owners who are currently staking in Keep Network should be allowed to stake in T without having to suffer the undelegation period and problematic shut down of tBTC v1 without tBTC v2 working. Exactly the same applies to NuCypher stakers on PRE. We will deploy special staking contract adapters for KEEP and NU allowing to honor existing KEEP and NU stakes in T network.
The key question we need to answer is how to make T staking contract the most extendable for future applications on T network while still leaving the choice for the users what risk they are willing to undertake by supporting specific applications. For example, looking at the current Keep Network staking contract, in the current format, it does not allow to easily extend network capabilities. It is a perfect match for random beacon and tBTC but could have some limitations for future applications. Specifically, Keep staking contract allows only to slash tokens and to seize 5% of the slashed stake. It does not allow, for example, to seize 100% of the stake and send it to coverage pool. Ideally, T staking contract would be more extendable and allowed for additional functionalities not available today.
Proposed architecture assumes one main TokenStaking contract for T network and several application staking contracts authorized on the main TokenStaking contract. The main staking contract will handle the delegation operation, will let authorizers to authorize application staking contracts up to the given stake amount, and will allow authorized application staking contracts to snatch(amount) of stake and do whatever they deem necessary with snatched amount: burn (slash) or seize by sending a part of it to tattletale, coverage pool, or anything else according to the application rules and needs. Off-chain clients will talk to per-application staking contracts.
To honor existing KEEP/NU stakes in T network we will deploy two adapters negotiating between existing KEEP/NU staking contracts and the new per-application staking contracts. Worth noting, there is a risk that not every application would be supported for existing stakers. For example, random beacon requires the staking contract to allow to seize tokens and send 5% of them to tattletale. If this is not supported by NU staking contracts and we decide that changing the beacon security model is not an option, NU stakers might not be able to run the random beacon. Similarly, there is no guarantee any future, post-tTBTC-v2 applications will support KEEP/NU stakers if the existing staking contracts lack some features that will be required by these applications. The minimum we are aiming for is that both existing KEEP and existing NU stakers can run tBTC v2 and ideally, both KEEP and NU stakers can run random beacon and PRE but it could be a stretch goal because of the staking contract limitation mentioned earlier.
Below is a pseudocode and an ugly drawing loosely presenting the idea:
```
// Keep Network staking contract
contract TokenStaking {
function slash(uint256 amount, address[] operators)
function seize(
uint256 amount,
uint256 rewardMultiplier,
address tattletale,
address[]operators
)
}
function KeepTStakingAdapter {
// translates TokenStaking from Keep Network into requirements of
// RandomBeaconTokenStaking and ECDSATokenStaking
}
// T Network main staking contract
function TokenStaking {
function delegate(
address operator,
address authorizer,
address beneficiary,
uint256 amount
)
/// Authorizes application's staking contract to snatch up to
/// maxStake of the previously delegated stake
function authorize(
address applicationStakingContract,
uint256 maxStake
) onlyAuthorizer(msg.sender)
function snatch(uint256 amount) onlyAuthorizedApplication
}
function RandomBeaconTokenStaking {
constructor(
KeepTStakingAdapter adapter
NuTStakingAdapter adapter
TokenStaking tStaking
)
function seize(
uint256 amount,
uint256 rewardMultiplier,
address tattletale,
address []operators
)
}
function ECDSATokenStaking {
constructor(
KeepTStakingAdapter adapter
NuTStakingAdapter adapter
TokenStaking tStaking
)
function slash(uint256 amount, address[] operators)
}
function SomeFunkyAppTokenStaking {
function slashToTheBoneAndSendToCovPool(address[] operators)
}
```
<img width="793" alt="image" src="https://user-images.githubusercontent.com/4712360/126352316-05c41d02-309b-40c7-b9e6-4b6218c5c9f6.png">
# Creating T grants
We will develop a new token grant contract based on a clone factory pattern with a separate per-grantee clone. The grant contract will accept an optional vending machine constructor parameter and will perform KEEP/NU<>T wrapping during the init procedure. The grant contract will also allow going back to KEEP/NU both for vested and released tokens and for the tokens vested but not yet released. Each individual clone will receive its own entry in the Vending Machine during its initiation when wrapping KEEP/NU→T. This entry will allow the grantee to come back to KEEP/NU in case they decide to do so. The grant contract will be based on a simplified version of the existing [Keep TokenGrant](https://github.com/keep-network/keep-core/blob/main/solidity/contracts/TokenGrant.sol) contract.
# Plan of the game
The approach presented in this issue is Keep Network proposition (@pdyraga, @nkuba on our side). All steps need to be discussed and agreed with NuCypher's @cygnusv and @vzotova.
We would like to do an initial implementation hoping that some parts of the plan proposed could be easier to understand with Solidity code and given that we already have some building blocks on our side:
- [ ] @pdyraga implements T token by incorporating `ERC20WithPermit` into this repo,
- [ ] @pdyraga proposes a Vending Machine implementation,
- [ ] @nkuba proposes simple staking contract implementation,
- [ ] @pdyraga proposes Token Grant implementation,
- [ ] @pdyraga, @nkuba, @cygnusv, @vzotova iterate on the final solution.