###### tags: `Final Report` YuzuSwap Audit === > Copyright © 2022 by Verilog Solutions. All rights reserved. > January 4, 2022 > by **Verilog Solutions** <!-- <span style="position:fixed; top:200px; right:400px; opacity:0.5; font-size: 20px; z-index:99;">watermark</span> --> ![Yuzu-SWAP-COVER](https://hackmd.io/_uploads/B17g_2dm5.png) This report presents our engineering engagement with YuzuSwap, one of the first DEX projects for the Emerald paratime on the Oasis Network. YuzuSwap is an AMM DEX with innovative trading incentive designs, such as the **trading pool share token (TPST)**. YuzuSwap's TPST design keeps track of DEX users' swap operations and provides rewards for these users. --- ## Table of Content [TOC] --- ## Project Summary YuzuSwap is a decentralized exchange on the Oasis Emerald paratime that includes incentives such as liquidity mining and trade mining. YuzuSwap follows a non-custodial, peer-to-peer, automated-market-maker model and aims to provide a safe, swift, and low-cost tool to discover and swap tokens within the Oasis ecosystem. The YuzuSwap platform itself is fully open to developers and members of the Yuzu DAO. ___ ## Service Scope Our review focused on the [**main** branch](https://github.com/Yuzu-swap/yuzuswap-contract/tree/main/contracts_for_review), specifically, commit hash [**12b06a57c53ec9eed3eadaded2afd93362d44d8b**](https://github.com/Yuzu-swap/yuzuswap-contract/tree/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review). Our auditing service for YuzuSwap includes the following two stages: - Pre-Audit Consulting Service - Audit Service 1. **Pre-Audit Consulting Service** As a part of the pre-audit service, the Verilog team worked closely with the YuzuSwap development to discuss potential vulnerability and smart contract development best practices in a timely fashion. Verilog team is very appreciative of establishing an efficient and effective communication channel with the YuzuSwap team, as new findings are often exchanged promptly and fixes were deployed quickly, during the preliminary report stage. 3. **Audit Service** The Verilog team conducted a thorough study of the YuzuSwap code, with the YuzuSwap architecture graph and UML graph presented below in the YuzuSwap Architecture section. The list of findings, along with the severity and solution, is available under section [**Findings & Improvement Suggestions**](#Findings-amp-Improvement-Suggestions). ___ ## YuzuSwap Architecture <figure> <center> <img src="https://i.imgur.com/70kX5KS.png" width="600" alt="WOOF Swap Architecture"> <center><em>Yuzu Swap Architecture</em></center></center> </figure> These are the major smart contracts in YuzuSwap: - `YuzuToken.sol` - `YuzuKeeper.sol` - `YuzuPark.sol` - `YuzuParkExt.sol` - `YuzuRouter.sol` - `YuzuSwapMining.sol` - `YuzuZap.sol` 1. `YuzuKeeper.sol` `YuzuKeeper` has the privilege to mint yuzu tokens to the registered applications and `dev` address. 1. `YuzuToken.sol` `YuzuToken` is a standard ERC20 token contract, that can be minted by `owner`. 1. `YuzuPark.sol` `YuzuPark` is the contract where it distributes yuzu tokens half-attenuationally as rewards for staking eligible tokens. 1. `YuzuParkExt.sol` `YuzuParkExt` is a extenstion for `YuzuPark`. Multiple tokens can be set as reward tokens besides the yuzu token. 1. `YuzuRouter.sol` It's where users can swap tokens and accumulate yuzu rewards for eligible pairs. 1. `YuzuSwapMining.sol` It's where users can withdraw their accumulated yuzu rewards when user use `YuzuRouter` to swap tokens of eligible pair. 1. `YuzuZap.sol` In `YuzuZap`, users can get lp tokens by supplying a single token. Users can also swap back to a single token with the lp token. 1. `YUZUTokenBlackHole.sol` @ address [0x00b9dCA177aa3DB6F344A455d9E0511a6Aa7ad8D](https://explorer.emerald.oasis.dev/address/0x00b9dCA177aa3DB6F344A455d9E0511a6Aa7ad8D/contracts) Its a blank contract deployed by YuzuSwap team acts like a blackhole( address(0) ) to burn all buy backed $YUZU token. --- ## Privileged Roles There is one main privileged role `owner`. It can: 1. Mint yuzu tokens in `YuzuToken.sol` 1. Add and publish `applications` in `YuzuKeeper.sol` 2. Add, set pools, set reward rate and set swap mining at `YuzuPark.sol`, `YuzuParkExt.sol`, `YuzuSwapMining.sol`, `YuzuRouter.sol`, `StandardReward.sol`. --- ## Findings & Improvement Suggestions <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span><span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span><span style=" background-color: #FFCA0F; color: #121212; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Medium</span><span style=" background-color: #FF6B4A; color: white; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Major</span><span style=" background-color: #FF0000; color: white; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Critical</span> | | Total | Acknowledged | Resolved | | ------------- | ----- | ------------ | -------- | | Critical | 3 | 3 | 3 | | Major | 0 | 0 | 0 | | Medium | 2 | 1 | 1 | | Minor | 9 | 7 | 5 | | Informational | 7 | 3 | 3 | ### Critical 1. Router address should be a variable set by owner (`YuzuZap.sol`: [L48](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L48), [L93](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L93), [L98](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L98), [L112](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L112), [L144](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L144), [165](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L165), [L171](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L171)).<span style=" background-color: #FF0000; color: white; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Critical</span> **Description**: Router address is being passed in as argument and token allowance for router is set to maximum. Attackers can deploy a set of swap and router contracts with the same interface to drain contracts' funds. **Recommendation**: Router address should be a variable set by owner to prevent exploits. **Result**: Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 2. `<address>.call()` should be used instead of `<address>.transfer()` to transfer native tokens (`YuzuZap.sol`:[L448](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L448)). <span style=" background-color: #FF0000; color: white; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Critical</span> **Description**: `<address>.call()` should be used instead of `<address>.transfer` to transfer native tokens. **Recommendation**: Use uniswap's `TransferHelper.safeTransferETH()` to transfer native token. **Result**: Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 3. Reset amount of rewarder contract at `emergencyWithdraw`(`YuzuParkExt.sol`: [L313](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L313)). <span style=" background-color: #FF0000; color: white; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Critical</span> **Description**: User amounts of rewarder contracts are not reset to zero. **Recommendation**: Reset User amounts of rewarder contracts to zero. ``` Solidity for (uint256 i = 0;i < _rewarders.length ; i ++ ) { IRewarder _rewarder = _rewarders[i]; if(address(_rewarder) != address(0)) { _rewarder.onYUZUReward(_pid,msg.sender, 0,0); } } ``` **Result:** Resolved in commit [6867b4b00980862cefc5feb8487e9bb98ae4e31c](https://github.com/Yuzu-swap/yuzuswap-contract/commit/6867b4b00980862cefc5feb8487e9bb98ae4e31c). ### Major No major issue was found. ### Medium 1. Add nonRentrant modifier for external functions:`zapInToken()`, `zapIn()`, `zapAcross()`, `zapOut()`, `zapOutToken()`, `swapToken()`, `swapToNative()` (`YuzuZap.sol`:[L48](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L48), [L93](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L93), [L98](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L98), [L112](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L112), [L144](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L144), [165](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L165), [L171](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L171)). <span style=" background-color: #FFCA0F; color: #121212; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Medium</span> **Description**: No nonReentrant modifier for those functions. **Recommendation**: Add nonReentrant modifier. **Result**: Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 4. Approve actual amount instead of maximum amount (`YuzuZap.sol`:[L180](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L180)). <span style=" background-color: #FFCA0F; color: #121212; font-size: 12px; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Medium</span> **Description**: Maximum amount is used for approval here. **Recommendation**: Modify the functions to approve actual amount instead of maximum amount. **Result**: This suggestion is not adopted. ### Minor 1. Require only receive native tokens from router address (`YuzuZap.sol`:[L46](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L46)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: Anyone can send native tokens to the contract **Recommendation**: Require only router can send native tokens to current contract. **Result**: This suggestion is not adopted. 2. Change `public` to `external` for external call only functions(`YuzuParkExt.sol`:[L123](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L123), [L149](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L149), [L242](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L242), [L280](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L280), [L313](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L313), `YuzuPark.sol`:[L96](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts/YuzuPark.sol#L96), [L120](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts/YuzuPark.sol#L120), [L190](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts/YuzuPark.sol#L190), [L217](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts/YuzuPark.sol#L217), [L234](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts/YuzuPark.sol#L234)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: `public` and `external` differs in gas usage. Also `public` allows calls made inside the contract. **Recommendation**: Change `public` to `external` for external call only functions. **Result:** Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81) and in commit [0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf](https://github.com/Yuzu-swap/yuzuswap-contract/commit/0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf#diff-9a6c59b5d1c32a2216e5ef562339019714ea15a43fe7fed2bee65a582b6b04ca). 4. Add check for pool Id to make sure the pool does not exist at `addPool()` and `add()` (`StandardReward.sol`:[L70](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L70), `YuzuPark.sol`:[L96](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuPark.sol#L96)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: Pool might already exist. **Recommendation**: For example, add the following requirement to check if pool id is valid. ``` Solidity require(poolInfo[_pid].lastRewardBlock == 0, "Pool already exists"); // or require(_pid >= poolInfo.length, "Pool already exists"); ``` **Result:** Not Resolved. 5. Add check for pool Id to make sure pool exist at `updatePool()` and `setPool()` (`YuzuParkExt.sol`:[L219](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L219), `YuzuPark.sol`:[L167](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuPark.sol#L167), `StandardReward.sol`:[L89](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L89), [L99](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L99)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: Pool might not exist. **Recommendation**: For example, add the following requirement to check if pool already added. ``` Solidity require(poolInfo[_pid].lastRewardBlock != 0, "Pool not exists"); // or require(_pid < poolInfo.length, "Pool not exists"); ``` **Result**: Not Resolved. 6. Some varibales can be immutable. (`YuzuZap.sol`:[L35](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuZap.sol#L35), `HalfAttenuationYuzuReward.sol`:[L13-L17](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/HalfAttenuationYuzuReward.sol#L13-L17)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: `WNATIVE` at `YuzuZap` and `startBlock`, `blockNumberOfHalfAttenuationCycle` and `yuzuPerBlock` at `HalfAttenuationYuzuReward` can be immutable. **Recommendation**: add `immutable` keyword to `WNATIVE`. **Result**: Resolved in commit [0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf](https://github.com/Yuzu-swap/yuzuswap-contract/commit/0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf#). 2. The visibility of function`getYuzuFromStartblock()` can be `pure` ([L41](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/HalfAttenuationYuzuReward.sol#L41)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: Function visibility can be restricted to `pure`. **Recommendation**: Change function visibility to `pure`. **Result:** Resolved in commit [0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf](https://github.com/Yuzu-swap/yuzuswap-contract/commit/0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf#diff-037feeeadc21ee7a1906b617e5ae8743629ee53e9f176f4626586f3435cee481). 1. Use `div` from `SafeMath` (`StandardReward.sol`:[L107](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L107), [L109](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L109), [L152](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L152), [L177](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L177), [L178](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L178), [L182](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L182)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: The `/` is used for division instead of `div`. **Recommendation**: Use `div` from `SafeMath`. **Result:** Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 1. Add Solidity pragma version. <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> **Description**: There is no soldity version been added to the YuzuSwapMining.sol. **Recommendation**: Add `pragma solidity 0.6.12;` as other smart contracts. **Result**: Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 4. Multiply before dividing (`YuzuKeeper`: [L117](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuKeeper.sol#L117)). <span style=" background-color: #698999; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Minor</span> ```solidity function _queryActualYUZUReward(uint256 _amount) internal view returns (uint256) { uint256 actualAmount = _amount.div(10).mul(7); return actualAmount; } ``` **Description**: Use `div` before `mul`. **Recommendation**: Use `mul` before `div` to prevent precision lost. ```solidity // suggested changes function _queryActualYUZUReward(uint256 _amount) internal view returns (uint256) { uint256 actualAmount = _amount.mul(7).div(10); return actualAmount; } ``` **Result:** This suggestion is not adopted. ### Informational 1. Seperate `interface`. <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: Currently, interfaces is inside the same file with contract. **Recommendation**: Seperate `interface`. **Result**: This suggestion is not adopted. 6. Call `massUpdatePools()` directly at functions `add` and `set` (`YuzuParkExt.sol`:[L130](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L130), [L157](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L157), `YuzuPark.sol`:[L102](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuPark.sol#L102), [L126](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuPark.sol#L126)). <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: The `_withUpdate` is always true. `massUpdatePools()` can be called directly. **Recommendation**: Remove `if` `else` check for `_withUpdate`. `massUpdatePools()` can be called directly. **Result:** Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 3. Modifies the logic of function `duplicatedTokenDetect()`. (`YuzuPark.sol`:[L254](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuPark.sol#L254), `YuzuParkExt.sol`:[L345](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuParkExt.sol#L345)). <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: the check for dulipcate tokens detection can be optimized. **Recommendation**: For example, use a mapping to track added tokens. **Result**: Resolved in commit [0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf](https://github.com/Yuzu-swap/yuzuswap-contract/commit/0d0caf24d4898dcd13ef803d8f29b1e6f2022eaf#diff-9a6c59b5d1c32a2216e5ef562339019714ea15a43fe7fed2bee65a582b6b04ca). 1. Input Multicheck and Limitation (`YuzuKeeper`: [L62](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuKeeper.sol#L62)). <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> ```solidity function addApplication(address _yuzuMember , uint256 _totalValue, uint256 _perBlockLimit,uint256 _startBlock ) public onlyOwner appNotPublished { YuzuApplicatioin storage app = applications[_yuzuMember]; app.yuzuMember = _yuzuMember; app.totalValue = _totalValue; app.transferedValue = 0; app.perBlockLimit = _perBlockLimit; app.startBlock = _startBlock; emit ApplicationAdded(_yuzuMember,_totalValue,_perBlockLimit,_startBlock); } ``` **Description**: As one of the most important functions, input `_totalValue` should be limited into a certain range (less than 10% of the total token supply), input `_perBlockLimit` should be limited into a certain range, input `_startBlock` should be limited after certain date. **Recommendation**: Add requirement for each of the input. ```solidity // suggested changes, limitation should be determined by the project team function addApplication(address _yuzuMember , uint256 _totalValue, uint256 _perBlockLimit,uint256 _startBlock ) public onlyOwner appNotPublished { require(_yuzuMember != address(0), "YUZUKEEPER: ZERO ADDRESS"); require(_totalValue <= yuzu.totalSupply().div(10), "YUZUKEEPER: NO MORE THAN 10% OF TOTAL SUPPLY"); require(_perBlockLimit <= 1e18, "YUZUKEEPER: PER BLOCK LIMITATION"); require(_startBlock >= block.timestamp, "YUZUKEEPER: START AFTER CERTAIN TIME"); ...... } ``` **Result:** This suggestion is not adopted. We suggest that the owner of the smart contract must be very careful when calling this function. 3. Logic Improvement for Function `RequestForYUZU()` (`YuzuKeeper`: [L79](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/YuzuKeeper.sol#L79)). <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: When 1 $YUZU is mint, 0.1 for investor, 0.1 for foundation, 0.1 for dev. The current logic is to send the above 0.3 $YUZU first before sending the leftAmount to the user. This design is a bit unfair for the unlucky users who mint the last bit of Yuzu. **Recommendation**: step 1: check how many $YUZU is left. step 2: adjust the mint amount to the leftover amount of $YUZU if the mint amount exceeds the leftover amount. step 3: mint based on the distribution. *external changes required: YuzuToken.sol needs to add a `circulatingSupply()` external view function to feed YuzuKeeper how many tokens have been mint out. **Result:** This suggestion is not adopted. 2. Add public view functions for `poolInfo.length` at `StandardReward.sol`.<span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: A view function can be added to check the `poolInfo.length` for the convenience of adding pools in the future. **Recommendation**: Add a public view function for `poolInfo.length` **Result:** Resolved in commit [7333cda08cf6afabeb633e03cbc07143e8fb6923](https://github.com/Yuzu-swap/yuzuswap-contract/commit/7333cda08cf6afabeb633e03cbc07143e8fb6923#diff-235e5f0a9bfcb1ede2d27b4baece9c6913190d25878f3fc01818b5d74945da81). 3. Unused variable `_pendingYUZU` at `onYUZUReward()` and `pendingToken()` (`StandardReward.sol`:[L145](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L145), [L168](https://github.com/Yuzu-swap/yuzuswap-contract/blob/12b06a57c53ec9eed3eadaded2afd93362d44d8b/contracts_for_review/StandardReward.sol#L168)). <span style=" background-color:mediumseagreen; font-size: 12px; color: white; border-radius:4px; padding: 1px 4px; font-weight: 500; display: inline-block; margin: 2px; letter-spacing: 0.3px">Informational</span> **Description**: Unused variable `_pendingYUZU`. **Recommendation**: Change the code to followings to remove compiler warnings for unused variables. ```Solidity // onYUZUReward function onYUZUReward( uint256 pid, address _user, uint256 lpToken, uint256 // using just uint256 without variable name will remove the warning ) { ... } // similarly for pendingToken function pendingToken(uint256 _pid, address _user, uint256) { ... } ``` **Result:** This suggestion is not adopted. --- ## Disclaimer Verilog receives compensation from one or more clients for performing the smart contract and auditing analysis contained in these reports. The report created is solely for Clients and published with their consent. As such, the scope of our audit is limited to a review of code, and only the code we note as being within the scope of our audit detailed in this report. It is important to note that the Solidity code itself presents unique and unquantifiable risks since the Solidity language itself remains under current development and is subject to unknown risks and flaws. Our sole goal is to help reduce the attack vectors and the high level of variance associated with utilizing new and consistently changing technologies. Thus, Verilog in no way claims any guarantee of security or functionality of the technology we agree to analyze. In addition, Verilog reports do not provide any indication of the technologies proprietors, business, business model, or legal compliance. As such, reports do not provide investment advice and should not be used to make decisions about investment or involvement with any particular project. Verilog has the right to distribute the Report through other means, including via Verilog publications and other distributions. Verilog makes the reports available to parties other than the Clients (i.e., “third parties”) – on its website in hopes that it can help the blockchain ecosystem develop technical best practices in this rapidly evolving area of innovation.