owned this note
owned this note
Published
Linked with GitHub
# GnoSwap Code Workshop
- https://beta.gnoswap.io/
- https://docs.gnoswap.io/contracts/overview
## Gnoswap Features
1. **Trading**
1. Swap Tokens
2. Swap wit Details
3. Token Price (VWAP)
2. **Providing Liquidity**
1. Create a Pool
2. Create a Position
3. Remove a Position
4. Reposition
5. Increase Liquidity
6. Decrease Liquidity
3. **Staking**
1. Stake Positions
2. Claim Rewards
3. Unstake Positions
4. Add Incentives
4. **Governance**
1. Delegate GNS
2. Create a Proposal
3. Vote
4. Claim Rewards
6. **Launchpad**
1. Create a Project
2. Deposit GNS
3. Claim Rewards
## Contract Refactor Planning
1. Scope (ordered by priority with folder's name) :
- Pool
- Position
- Router
- Staker
- Governance
- LaunchPad
- Emission
- GNS
- GNFT
- ProtocolFee
- CommunityPool
- xGNS
- Common
### Refactoring Rules
1. refactor per contract (not refactoring in parallels)
2. single person for single file (to avoid conflict when we merge)
3. must write unit test codes
1. target: functions with calculation(computation) or chaing state
2. filename: {file_name}_test.gno
3. policy
1. function:testcode should be correspondence as 1:1
2. includes both successful and panic
4. make interface to use mock data
5. implements duplication code in package(or common realm) and re-use it.
6. use `type struct` for higher cohesion
7. DO NOT USE `map` ( use `avl.tree` ) // if key is numeric value, use `p/seqid`
8. code style
1. single function should not be more than 50 lines
2. use tlin to check complexitiy (score should be less than 15)
3. naming rule
1. _get, _rpc -> api.gno, getter.gno
2. for variable represents `path` -> xxxPath
3. `amount` -> xxxAmount
4. position token id -> lpTokenId
9. comments
1. add doc.gno file (as package level comments)
2. add ref link
10. function that doesn't change state -> to be moved to /p, no /r.
11. for address, use `std.Address` not `string`
12. for early return, add guard logic
13. when we use `string` type to pass uint256 value as primitve, use prefix
1. ex) `_liquidityAmount`
### (gnoswap) contract related discussion
#### relates to https://github.com/gnolang/gno/issues/1982
1. `gno test`
1. XXX_test.gno // unable to run only single file -> plans to support it(like go) ??
2. XXX_test.gno // inside test file, assume there are two test functinos `TestFunc1`, `TestFunc2`.
1. `TestFunc2` gets affected by behavior in `TestFunc1`
2. if `TestFunc1` changes, we need to change every test code (because for gnoswap we need to check every number(token amount)
- ex) [gnoswap staker tc](https://gist.github.com/r3v4s/d53e6793ff67f10ccf3360cb337c1c44)
4. Any way to reset realm states?
2. `prevRealm`
1. when callframe like below, we need to pass `prevRealm().Addr()` as paramter every time which being overhead.
```go
// contract A
func EntryPointFromTransaction() {
caller := std.PrevRealm().Addr()
B.Bb(caller)
}
// contract B
func Bb(caller std.Address) {
// action...
C.Cc(caller)
}
// contract C
func Cc(caller std.Address) {
if ownerOf(tokenId) == caller {
// action...
}
}
```
-> when realm calls another realms, to get(verify) address that made transaction
--> do we need to pass caller as paramter every time ??
---> if so, this is being like unique gno pattern. Is this intended ??
### As Is -> To Be
## Workflows and improvements
### As-Is
#### [Workflow]

#### [Problems]
1. strong dependency on chain state as contract data synchronization is performed by ABCI query on backend
- Gnoswap synchronization function, executed every block
- ABCI query request function for reward calculation
- Data for calculating staking rewards ABCI query request function (every 20 blocks)
- Data for calculating incentivize rewards ABCI query request function (every 20 blocks)
- TotalSupply ABCI Query Request Function for GRC20 Tokens
- ABCI query request function, DB update after checking transaction events in a block
- Many ABCI query calls can overload the chain, and the service becomes unstable when the chain's response is slow or lost.
2. Server application is large in size and not separated, making it difficult to manage service operations
- API server called from the interface
- Servers that fetch blocks and transactions and sink data
3. High coupling between domains at the code level and lack of layer separation
---
### To-Be
#### [Workflow]

#### Improvement directions and goals
1.Reduce dependency on chain and enable application-specific independent behavior.
- Reduce dependency on the chain by having a separate application to collect blocks and transactions that acts as an indexer
- Processing Gnoswap data based on transaction data and event data without using ABCI queries
2. Design with the goal of scalable and stable operation.
- Manage domain-specific apps and aim for loose coupling
- Communication between Handler <-> domain apps in the form of REST API-based messages (gRPC is also under consideration)
- Handlers that process requests use a message queue to manage and serve requests.
3. Enforce code management policies to improve code quality and maintain stability.
- Test case-based reviews, service policies, and thresholds for handling
- Clearly separate layers based on roles: handlers, service logic, data source access, etc.
## Discussion
- How should make the GnoSwap realms as a representative smart-contracts that maximize Gno 120%? Any tips on making it more gno-ish?
- Is there anything we can improve as a decentralized application using the gno.land blockchain from a software architecture stand point of view?
- Are there any Gno Team-specific methods or techniques we can learn to strengthen code review processes to increase reliability and the quality of the codebase?