Skip to content

Commit 935ba91

Browse files
joshuahannanarrivetsjordanschalmdanukumananJeffreyDoyle
authored
FEATURE: Epoch contracts (#63)
* Epoch contract skeleton * make generate * make ci * Adds staking enabled field (#104) * first draft of epoch staking * adding stakingEnabled * added staking enabled field * revert epoch contract * make test * ci * First Draft of clusterQC contract (#66) * testing draft of clusterQC contract * first draft of QC contracts and happy path tests * change name of QC contract * PR comments and node voted * add more cases * refactor cluster creation * small fixes and epoch additions * Epoch smart contract integration * fixed bug and reverted epoch contract * regenerate assets * Adds metadata claimed fields to reduce gas use (#106) * add metadata claimed fields * PR comments * moving derived info to NodeInfo struct (#113) * fixing get total balance * Adds DKG contract and transactions (#108) * first draft of DKG * add completed return * draft of dkg transactions * add admin transactions * removing phases * tests for DKG * PR comments * changing field name and adding comments * removeing >0 checks * Epoch Lifecycle contract (#117) * add latest epoch contract * removeing >0 checks * first draft of epoch contract * addressing PR comments * comments * ci * adds test helpers * changing fields tests * few more util changes * more test utils and tests * added comments * epoch setup registration * happy path epoch setup * epoch committed and end epoch * reset test * comments * comments * Add reward APY and separate rewards payment (#132) * add latest epoch contract * first draft of epoch contract * addressing PR comments * comments * ci * adds test helpers * changing fields tests * few more util changes * more test utils and tests * added comments * epoch setup registration * happy path epoch setup * epoch committed and end epoch * reset test * comments * comments * rewards * rewards reorg * add reward set call and test * Un-restrict QC and DKG registration (#133) * add latest epoch contract * first draft of epoch contract * addressing PR comments * comments * ci * adds test helpers * changing fields tests * few more util changes * more test utils and tests * added comments * epoch setup registration * happy path epoch setup * epoch committed and end epoch * reset test * comments * comments * rewards * rewards reorg * dkg register * add reward set call and test * fixing PR comments * fix result (#139) * approveNodes function (#143) * Removes new staking contract fields and use storage instead (#145) * approveNodes function * remove new fields and use storage instead * make upgrade work * typo * add tests and PR comment fixes * changes fields to functions (#148) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * test upgrade and update dependencies * Remove panic from get_latest_whiteboard_messages.cdc We shouldn't panic when someone requests broadcast messages with an out-of-range start index; just return an empty array * test * Decouples rewards payment from the end of the epoch (#171) * decouple rewards payment * move rewards payment to staking * only pay rewards once and split scale functions * add rewardsPaid field * Restoring changes that were lost from three branches (#174) * dkg nil submissions and end epoch * add method to get canonical final submission * PR comments * Adds support for nil submissions to the DKG and ends DKG and QC at the end of epoch (#164) * dkg nil submissions and end epoch * PR comments * add template package and test * Add script to get canonical final DKG submission (#166) * add method to get canonical final submission * add template package and test Co-authored-by: joshuahannan <[email protected]> * Update DKG Ordering Comment * make assets Co-authored-by: Jordan Schalm <[email protected]> Co-authored-by: Danu <[email protected]> * Include voter ID in cluster quorum certificates (#173) * add voter ID to cluster QC in epoch commit this is necessary both to validate individual votes and to construct the Quorum Certificate structure (ie. for aggregate validation) * update generated assets * add block ID fields * remove block ID Co-authored-by: joshuahannan <[email protected]> * Integrate changes from master (#178) * adds admin capability transfer (#172) * adds capability transfer * remove force unwrap * General upgrades to staking contract (#149) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * test upgrade and update dependencies * update versions and add comments * refactors test utilities (#176) * refactors test utilities * add comments * adding event back (#177) * Merge Staking Collection with Epochs (#179) * WIP proxy collection * skeleton of collection contract * Josh/stakingbugs (#125) * [StakingCollection] -- Implements StakingCollection methods * [StakingCollection] -- Implements getter methods and updates preconditions * [StakingCollection] -- Implements deposit tokens method * [StakingCollection] -- Implements public getter methods * [StakingCollection] -- Updates function descriptions * [StakingCollection] -- Adds initial (almost working) implementation of StakingCollection tests * get deployment working (#123) * [StakingCollection] -- Resolves cadence errors * fixing all normal bugs Co-authored-by: Jeffrey Doyle <[email protected]> * [StakingCollection] -- Adds first pass of StakingCollection transactions (#127) * templates and access * [StakingCollection] (#120) * [StakingCollection] -- Adds template generators * [StakingCollection] -- Adds state query scripts * Adds tests and fixes for the staking collection contract (#134) * fix deposit and add comments * get tokens tests and transactions * account creation change * setup fixes * fix bugs * staking registration * refactor verification * subtract account minimum balance when getting locked account balance (#136) * subtract account minimum balance * add comment * deposit tests * Adds get tokens tests (#137) * stakenew tokens * Updates to deposit unlocked tokens to locked acct before staking new tokens (#138) * Updates to deposit unlocked tokens to locked acct before staking new tokens * Includes go mod and sum files * Adds assets go * Updates go sum * all other staking tests * run tests * verify staking tests * checking unlock limit * Adds closeStake method to StakingCollection (#142) * Adds closeStake method to StakingCollection * Passes in delegatorID to DelegatorInfo constructor * Updates StakingCollection tests * Updates StakingCollection CloseStake tests * Updates StakingCollection CloseStake tests * refactor close stake tests Co-authored-by: Jeff Doyle <[email protected]> * refactor locked vault and add comments (#147) * Staking Collection Check (#151) * Adds functionality to check if an account is configured with a StakingCollection or not * Updates to doesAccountHaveStakingCollection naming * Updates doesAccountHaveStakingCollection function description * adds admin capability transfer (#172) * adds capability transfer * remove force unwrap * update versions and add comments * General upgrades to staking contract (#149) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * test upgrade and update dependencies * update versions and add comments * revert staking proxy change * refactors test utilities (#176) * refactors test utilities * add comments * adding event back (#177) Co-authored-by: Jeffrey Doyle <[email protected]> * Epoch remove node (#183) * WIP proxy collection * skeleton of collection contract * Josh/stakingbugs (#125) * [StakingCollection] -- Implements StakingCollection methods * [StakingCollection] -- Implements getter methods and updates preconditions * [StakingCollection] -- Implements deposit tokens method * [StakingCollection] -- Implements public getter methods * [StakingCollection] -- Updates function descriptions * [StakingCollection] -- Adds initial (almost working) implementation of StakingCollection tests * get deployment working (#123) * [StakingCollection] -- Resolves cadence errors * fixing all normal bugs Co-authored-by: Jeffrey Doyle <[email protected]> * [StakingCollection] -- Adds first pass of StakingCollection transactions (#127) * templates and access * [StakingCollection] (#120) * [StakingCollection] -- Adds template generators * [StakingCollection] -- Adds state query scripts * Adds tests and fixes for the staking collection contract (#134) * fix deposit and add comments * get tokens tests and transactions * account creation change * setup fixes * fix bugs * staking registration * refactor verification * subtract account minimum balance when getting locked account balance (#136) * subtract account minimum balance * add comment * deposit tests * Adds get tokens tests (#137) * stakenew tokens * Updates to deposit unlocked tokens to locked acct before staking new tokens (#138) * Updates to deposit unlocked tokens to locked acct before staking new tokens * Includes go mod and sum files * Adds assets go * Updates go sum * all other staking tests * run tests * verify staking tests * checking unlock limit * Adds closeStake method to StakingCollection (#142) * Adds closeStake method to StakingCollection * Passes in delegatorID to DelegatorInfo constructor * Updates StakingCollection tests * Updates StakingCollection CloseStake tests * Updates StakingCollection CloseStake tests * refactor close stake tests Co-authored-by: Jeff Doyle <[email protected]> * refactor locked vault and add comments (#147) * Staking Collection Check (#151) * Adds functionality to check if an account is configured with a StakingCollection or not * Updates to doesAccountHaveStakingCollection naming * Updates doesAccountHaveStakingCollection function description * adds admin capability transfer (#172) * adds capability transfer * remove force unwrap * update versions and add comments * General upgrades to staking contract (#149) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * test upgrade and update dependencies * update versions and add comments * revert staking proxy change * refactors test utilities (#176) * refactors test utilities * add comments * adding event back (#177) * adds remove and transfer node ability (#182) * adds remove and transfer node ability * fixing dependencies Co-authored-by: Jeffrey Doyle <[email protected]> * adds start view and end view to resetEpoch (#186) * add start view and end view * add phase precondition * Changes from staking collection (#190) * WIP proxy collection * skeleton of collection contract * Josh/stakingbugs (#125) * [StakingCollection] -- Implements StakingCollection methods * [StakingCollection] -- Implements getter methods and updates preconditions * [StakingCollection] -- Implements deposit tokens method * [StakingCollection] -- Implements public getter methods * [StakingCollection] -- Updates function descriptions * [StakingCollection] -- Adds initial (almost working) implementation of StakingCollection tests * get deployment working (#123) * [StakingCollection] -- Resolves cadence errors * fixing all normal bugs Co-authored-by: Jeffrey Doyle <[email protected]> * [StakingCollection] -- Adds first pass of StakingCollection transactions (#127) * templates and access * [StakingCollection] (#120) * [StakingCollection] -- Adds template generators * [StakingCollection] -- Adds state query scripts * Adds tests and fixes for the staking collection contract (#134) * fix deposit and add comments * get tokens tests and transactions * account creation change * setup fixes * fix bugs * staking registration * refactor verification * subtract account minimum balance when getting locked account balance (#136) * subtract account minimum balance * add comment * deposit tests * Adds get tokens tests (#137) * stakenew tokens * Updates to deposit unlocked tokens to locked acct before staking new tokens (#138) * Updates to deposit unlocked tokens to locked acct before staking new tokens * Includes go mod and sum files * Adds assets go * Updates go sum * all other staking tests * run tests * verify staking tests * checking unlock limit * Adds closeStake method to StakingCollection (#142) * Adds closeStake method to StakingCollection * Passes in delegatorID to DelegatorInfo constructor * Updates StakingCollection tests * Updates StakingCollection CloseStake tests * Updates StakingCollection CloseStake tests * refactor close stake tests Co-authored-by: Jeff Doyle <[email protected]> * refactor locked vault and add comments (#147) * Staking Collection Check (#151) * Adds functionality to check if an account is configured with a StakingCollection or not * Updates to doesAccountHaveStakingCollection naming * Updates doesAccountHaveStakingCollection function description * adds admin capability transfer (#172) * adds capability transfer * remove force unwrap * update versions and add comments * General upgrades to staking contract (#149) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * test upgrade and update dependencies * update versions and add comments * revert staking proxy change * refactors test utilities (#176) * refactors test utilities * add comments * adding event back (#177) * adds remove and transfer node ability (#182) * adds remove and transfer node ability * fixing dependencies * Addresses PR Comments and adds some events (#188) * fixing suggestions * separate borrow * Adds struct and fields for machine account records (#189) * adds machine account fields * remove provider * Update contracts/FlowStakingCollection.cdc * remove apostrophe Co-authored-by: Jeffrey Doyle <[email protected]> * Adds machine account functionality to staking collection (#184) * first draft of machine account * getting normal tests running * register node tests * add public key check and test * add machine account refactor * FEATURE: Staking Collection contract (#119) (#192) * WIP proxy collection * skeleton of collection contract * Josh/stakingbugs (#125) * [StakingCollection] -- Implements StakingCollection methods * [StakingCollection] -- Implements getter methods and updates preconditions * [StakingCollection] -- Implements deposit tokens method * [StakingCollection] -- Implements public getter methods * [StakingCollection] -- Updates function descriptions * [StakingCollection] -- Adds initial (almost working) implementation of StakingCollection tests * get deployment working (#123) * [StakingCollection] -- Resolves cadence errors * fixing all normal bugs Co-authored-by: Jeffrey Doyle <[email protected]> * [StakingCollection] -- Adds first pass of StakingCollection transactions (#127) * templates and access * [StakingCollection] (#120) * [StakingCollection] -- Adds template generators * [StakingCollection] -- Adds state query scripts * Adds tests and fixes for the staking collection contract (#134) * fix deposit and add comments * get tokens tests and transactions * account creation change * setup fixes * fix bugs * staking registration * refactor verification * subtract account minimum balance when getting locked account balance (#136) * subtract account minimum balance * add comment * deposit tests * Adds get tokens tests (#137) * stakenew tokens * Updates to deposit unlocked tokens to locked acct before staking new tokens (#138) * Updates to deposit unlocked tokens to locked acct before staking new tokens * Includes go mod and sum files * Adds assets go * Updates go sum * all other staking tests * run tests * verify staking tests * checking unlock limit * Adds closeStake method to StakingCollection (#142) * Adds closeStake method to StakingCollection * Passes in delegatorID to DelegatorInfo constructor * Updates StakingCollection tests * Updates StakingCollection CloseStake tests * Updates StakingCollection CloseStake tests * refactor close stake tests Co-authored-by: Jeff Doyle <[email protected]> * refactor locked vault and add comments (#147) * upgrades to staking contract to prepare for epochs * update from collection * update to latest version * Staking Collection Check (#151) * Adds functionality to check if an account is configured with a StakingCollection or not * Updates to doesAccountHaveStakingCollection naming * Updates doesAccountHaveStakingCollection function description * test upgrade and update dependencies * update versions and add comments * revert staking proxy change * adds remove and transfer node ability (#182) * adds remove and transfer node ability * fixing dependencies * Addresses PR Comments and adds some events (#188) * fixing suggestions * separate borrow * Adds struct and fields for machine account records (#189) * adds machine account fields * remove provider Co-authored-by: Jeffrey Doyle <[email protected]> Co-authored-by: Jeffrey Doyle <[email protected]> * updates comments and changes resetEpoch parameters (#194) * updates comments and changes resetEpoch parameters * responding to PR comments * Epoch Metadata to account storage (#196) * updates comments and changes resetEpoch parameters * use storage * add comment * remove type specification * Withdraw from machine account method (#197) * updates comments and changes resetEpoch parameters * use storage * add comment * remove type specification * adds method to withdraw tokens from the machine account * make argument nil * change epochcommitted to epochcommit (#199) * adds create machine account transaction (#202) * adds create machine account transaction * use string instead of byte array * not optional * Validate staking contract keys when nodes register (#204) * adds create machine account transaction * use string instead of byte array * not optional * key verification and tests * add PoP comments * fixes locked tokens tests * add a script to build the crypto dependency * uncomment test functions * fix go mod and sum * add the crypto build to the internal lib/go/test targets * git clone using https * export the GOPATH * use a single run command in ci.yaml * use sudo for write permission in GOPATH * use tmate to debug * activate tmate only on failures * use go 1.15 and grant GOPATH permissions * test permissions before chmod * review comments * ci Co-authored-by: Tarak Ben Youssef <[email protected]> * Adds QC signature validation and vote counting (#205) * adds create machine account transaction * first draft of signature verification * use string instead of byte array * not optional * key verification and tests * adds QC signature verification and tests * first draft of qc counting * add PoP comments * fixes locked tokens tests * add a script to build the crypto dependency * uncomment test functions * fix go mod and sum * add the crypto build to the internal lib/go/test targets * git clone using https * export the GOPATH * use a single run command in ci.yaml * use sudo for write permission in GOPATH * use tmate to debug * activate tmate only on failures * use go 1.15 and grant GOPATH permissions * account creation * test permissions before chmod * review comments * ci * PR comments * change name to FlowClusterQC * clean up flow-go crypto dependency (#206) * restrict chmod permissions * remove tmate from ci Co-authored-by: joshuahannan <[email protected]> * PR comments and testing more nodes Co-authored-by: Tarak Ben Youssef <[email protected]> Co-authored-by: Tarak Ben Youssef <[email protected]> * make ci Co-authored-by: arrivets <[email protected]> Co-authored-by: Jordan Schalm <[email protected]> Co-authored-by: Danu <[email protected]> Co-authored-by: Jeffrey Doyle <[email protected]> Co-authored-by: Tarak Ben Youssef <[email protected]> Co-authored-by: Tarak Ben Youssef <[email protected]>
1 parent 2f5add6 commit 935ba91

File tree

102 files changed

+10161
-1423
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+10161
-1423
lines changed

.github/workflows/ci.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ jobs:
99
- uses: actions/checkout@v2
1010
- uses: actions/setup-go@v1
1111
with:
12-
go-version: '1.13.10'
13-
- run: make ci
12+
go-version: '1.15'
13+
- name: Run tests
14+
run: export GOPATH=$HOME/go && make ci
15+

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.PHONY: test
2-
test:
2+
test:
33
$(MAKE) generate -C lib/go
44
$(MAKE) test -C lib/go
55

README.md

+58-10
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
These are the smart contracts that define the core functionality of the Flow protocol.
44

5-
## What is Flow?
5+
# What is Flow?
66

77
Flow is a new blockchain for open worlds. Read more about it [here](https://www.onflow.org/).
88

9-
## What is Cadence?
9+
# What is Cadence?
1010

1111
Cadence is a new Resource-oriented programming language
1212
for developing smart contracts for the Flow Blockchain.
@@ -16,7 +16,7 @@ We recommend that anyone who is reading this should have already
1616
completed the [Cadence Tutorials](https://docs.onflow.org/docs/getting-started-1)
1717
so they can build a basic understanding of the programming language.
1818

19-
### FlowToken
19+
## FlowToken
2020

2121
`contracts/FlowToken.cdc`
2222

@@ -28,13 +28,13 @@ for more information.
2828

2929
You can find transactions for using the Flow Token in the `transactions/flowToken` directory.
3030

31-
### Fee Contract
31+
## Fee Contract
3232

3333
`contracts/FlowFees.cdc`
3434

3535
This contract defines fees that are spent for executing transactions and creating accounts.
3636

37-
### Storage Fee Contract
37+
## Storage Fee Contract
3838

3939
`contracts/FlowStorageFees.cdc`
4040

@@ -43,7 +43,7 @@ There is a minimum balance that an account needs to maintain in its main `FlowTo
4343
in order to pay for the storage it uses.
4444
You can see [more docs about storage capacity and fees here.](https://docs.onflow.org/concepts/storage/#overview)
4545

46-
### Service Account Contract
46+
## Service Account Contract
4747

4848
`contracts/FlowServiceAccount.cdc`
4949

@@ -53,7 +53,7 @@ functionality for flow tokens.
5353

5454
You can find transactions for interacting with the service account contract in the `transactions/FlowServiceAccount` directory.
5555

56-
### Flow Identity Table, Staking, and Delegation Contract
56+
## Flow Identity Table, Staking, and Delegation Contract
5757

5858
`contracts/FlowIDTableStaking.cdc`
5959

@@ -69,20 +69,68 @@ in the `transactions/idTableStaking` directory.
6969
You can also find scripts for querying info about staking and stakers in the `transactions/idTableStaking/scripts/` directory.
7070
These scripts are documented in the [staking scripts section of the docs](https://docs.onflow.org/staking/scripts/)
7171

72-
### Flow Locked Tokens contract
72+
## Flow Locked Tokens contract
7373

7474
`contracts/LockedTokens.cdc`
7575

7676
This contract manages the two year lockup of Flow tokens that backers purchased in the initial
7777
token sale in October of 2020. See more documentation about `LockedTokens` [here.](https://docs.onflow.org/flow-token/locked-account-setup/)
7878

79-
## Testing
79+
## Flow Staking Collection Contract
80+
81+
`contracts/FlowStakingCollection.cdc`
82+
83+
A Staking Collection is a resource that allows its owner to manage multiple staking
84+
objects in a single account via a single storage path, and perform staking and delegation actions using both locked and unlocked Flow.
85+
86+
Before the staking collection, accounts could use the instructions in [the unlocked staking guide](https://docs.onflow.org/staking/unlocked-staking-guide/)
87+
to stake with tokens. This was a bit restrictive, because that guide (and the corresponding transactions) only supports one node and one delegator object
88+
per account. If a user wanted to have more than one per account, they would either have to use custom transactions with custom storage paths for each object,
89+
or they would have had to use multiple accounts, which comes with many hassles of its own.
90+
91+
The same applies to the [locked tokens staking guide](https://docs.onflow.org/staking/locked-staking-guide/).
92+
We only built in support for one node and one delegator per account.
93+
94+
The staking collection is a solution to both of these deficiencies. When an account is set up to use a staking collection,
95+
the staking collection recognizes the existing locked account capabilities (if they exist) and unlocked account staking objects,
96+
and incorporates their functionality so any user can stake for a node or delegator through a single common interface, regardless of
97+
if they have a brand new account, or have been staking through the locked account or unlocked account before.
98+
99+
### Is the staking collection mandatory
100+
101+
The Flow team will be using the staking collection for Flow Port by default and we recommend that other services use it instead of any of the other account setups. If you provide a staking service for ledger or blocto users, you will need to upgrade to this if you want to give your users access to the entire functionality of their account if they are also using Flow Port. If their entire interaction with staking is through Flow Port, then all the changes are handled for them and there is nothing for you to worry about.
102+
103+
### Staking Collection Technical features
104+
105+
* The staking collection contract stores [a dictionary of staking objects](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc#L68) from the staking contract that are used to manage the stakers tokens. Since they are dictionaries, there can be as many node or delegator objects per account as the user wants.
106+
* The resource only has one set of staking methods, which route the call to the correct staking object based on the arguments that the caller specifies. (nodeID, delegatorID)
107+
* The contract also stores an [optional capability to the locked token vault](https://github.com/onflow/flow-core-contracts/blob/master/contracts/FlowStakingCollection.cdc#L63) and [locked tokens `TokenHolder` resource](https://github.com/onflow/flow-core-contracts/blob/master/ontracts/FlowStakingCollection.cdc#L73). This is only used if the user already has a locked account. The staking collection does not change the locked account setup at all, it only has access to it and to the locked vault.
108+
* The collection makes the staking objects and vault capability fields private, because since it has access to the locked tokens, it needs to mediate access to the staking objects so users cannot withdraw tokens that are still locked from the sale. The resource has fields `unlockedTokensUsed` and `lockedTokensUsed`, to keep track of how many locked and unlocked tokens are being used for staking in order to allow the user to withdraw the correct amount when they choose to.
109+
* The staking collection contract is a brand new contract that will be deployed to the same account as the existing locked tokens contract. A few of the fields on the `LockedTokens` contract have been updated to have `access(account)` visibility instead of `access(self)` because the staking collection contract needs to be able to access to them in order to work properly.
110+
* We also included a public interface and getters in the contract so you can easily query it with an address to get node or delegator information from a collection.
111+
112+
Looking for feedback on design decisions, implementation details, any events that would be useful to include in the contract, and whatever you feel is important!
113+
114+
We intend for this to be the method that all Flow Port users (ledger, blocto, etc) use for the forseeable future. When we enable it in Flow Port, we will ask every user to run a transaction to set up their account to use the staking collection from then on.
115+
116+
117+
## Epoch Contracts
118+
119+
`contracts/epochs/FlowEpoch.cdc`
120+
`contracts/epochs/FlowClusterQC.cdc`
121+
`contracts/epochs/FlowDKG.cdc`
122+
123+
These contracts manage the epoch functionality of Flow, the mechanism by which Flow tracks time, changes the approved list of node operators, and bootstrap consensus between different nodes.
124+
`FlowClusterQC.cdc` and `FlowDKG.cdc` manage processes specific to collector and consensus nodes, respectively.
125+
`FlowEpoch.cdc` ties all of the epoch and staking contracts together into a coherent state machine that will run on its own.
126+
127+
# Testing
80128

81129
To run the tests in the repo, use `make test`.
82130

83131
These tests need to utilize the transaction templates that are contained in `transactions/`.
84132

85-
## Getting Transaction Templates
133+
# Getting Transaction Templates
86134

87135
If you need to use the contracts and transaction templates we have provided in an app, you don't necessarily
88136
need to copy and paste them into your code. We plan on providing packages for different

0 commit comments

Comments
 (0)