# Unirep Onchain Refactor
I propose some tweaks to the structures in the Unirep protocol to take advantage of L2 network properties.
## GST
Currently the GST stores leaves that are the root of a user state tree. Each user state tree stores all attester balances for a user.
**Proposed change**: each attester has their own state tree for each epoch. The leaves of this tree are `H(idenNullifier, attesterId, epoch, posRep, negRep, graffiti, signUp)`.
Users can prove their rep in a certain epoch for a certain attester more easily (1 merkle proof instead of 2).
## Epoch Tree
Currently we have 1 epoch tree per epoch. The full SMT is stored on chain.
**Proposed change**: 1 epoch tree per attester, per epoch. Store only the root on chain.
These trees should be stored offchain and operated using ZK proofs. When an attestation is created we update the hashchain for the epoch key receiving the attestation. We can do this in zk with the following:
**Input signals**
- epochRoot
- epochKey
- posRep
- negRep
- graffiti
- signUp
- oldHashchain
- oldHashchain merkle inclusion proof
**Output signals**
- newEpochRoot
- leaf = H(oldHashchain, H(posRep, negRep, graffiti, signUp))
- The new attestation hashchain
- epochKey (leaf index)
In ZK we check that the old leaf exists for the root. We then calculate the new leaf and calculate the new tree root. We verify this proof onchain and then emit an event with the new leaf and store the new root.
### Advantages
- Different epoch keys for different attesters in the same epoch
- User transitions will be done per-attester
- Malicious attesters can't increase proving time for other attester state transitions
- Lower gas cost
- Less onchain storage used
### Disadvantages
- Every attestation requires a ZK proof
- Proof can be calculated by anyone
## Summary
Using this structure we'll have 1 incremental tree and 1 smt per attester, per epoch. The full incremental tree and SMT root are stored onchain. The user state tree is removed completely.