Platform: Code4rena
Start Date: 17/03/2023
Pot Size: $36,500 USDC
Total HM: 10
Participants: 98
Period: 3 days
Judge: leastwood
Total Solo HM: 5
Id: 223
League: ETH
Rank: 47/98
Findings: 2
Award: $34.80
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Sathish9098
Also found by: 0xAgro, 0xSmartContract, 0xdaydream, 0xnev, Awesome, Aymen0909, BRONZEDISC, Bauchibred, Deathstore, Diana, IceBear, Jerry0x, Kresh, Matin, Rolezn, Stryder, T1MOH, Udsen, adriro, alejandrocovrr, atharvasama, codeslide, cryptonue, descharre, igingu, jack, joestakey, libratus, lukris02, luxartvinsec, nadin, nasri136, reassor, scokaf, shark, slvDev, tnevler
22.7749 USDC - $22.77
S No. | Issue | Instances |
---|---|---|
[01] | Avoid using tx.origin | 4 |
[02] | _safemint() should be used rather than _mint() wherever possible | 3 |
[03] | Denial of Service - tokenToName and nameToToken growing indefinitely | 2 |
[04] | Solmate safetransferfrom does not check the codesize of the token address, which may lead to fund loss | 2 |
[05] | Use a more recent version of solidity | 5 |
tx.origin
 is a global variable in Solidity that returns the address of the account that sent the transaction.
Using the variable could make a contract vulnerable if an authorized account calls a malicious contract. You can impersonate a user using a third party contract.
There are 4 instances of this issue
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-bio-protocol/src/Bio.sol
File: main/canto-bio-protocol/src/Bio.sol 36: turnstile.register(tx.origin);
File: main/canto-namespace-protocol/src/Namespace.sol 84: turnstile.register(tx.origin);
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol
File: main/canto-namespace-protocol/src/Tray.sol 113: turnstile.register(tx.origin);
File: main/canto-pfp-protocol/src/ProfilePicture.sol 63: turnstile.register(tx.origin);
_mint()
 is discouraged in favor of _safeMint()
 which ensures that the recipient is either an EOA or implements IERC721Receiver
. Both open OpenZeppelin and solmate have versions of this function so that NFTs aren’t lost if they’re minted to contracts that cannot transfer them back out.
There are 3 instances of this issue
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-bio-protocol/src/Bio.sol
File: main/canto-bio-protocol/src/Bio.sol 126: _mint(msg.sender, tokenId);
File: main/canto-namespace-protocol/src/Namespace.sol 177: _mint(msg.sender, namespaceIDToMint);
File: main/canto-pfp-protocol/src/ProfilePicture.sol 86: _mint(msg.sender, tokenId);
State variables tokenToName
 and nameToToken
 are growing indefinitely, this might lead to expensive transactions and effectively denial of service for the user when calling burn
 function that requires iterations over the whole arrays.
The contract is using tokenToName
 and nameToToken
 to track token ids and associated names for tokens. This helps with parsing state variables that contain data for all tokens. The elements for these are deleted by delete tokenToName[_id]
, delete nameToToken[associatedName]
, however the delete is only setting data located at the given index to zero. This make all element re-parsed every time the function is called, making the user consuming more gas. This results in denial of service,
There are 2 instances of this issue
File: main/canto-namespace-protocol/src/Namespace.sol 189: delete tokenToName[_id]; 190: delete nameToToken[associatedName];
It is recommended to remove elements from the arrays tokenToName
/nameToToken
 using pop()
 function when deleting tokens.
In fuse()
 and buy()
, the safetransferfrom
 doesn’t check the existence of code at the token address. This is a known issue while using solmate’s libraries.
Hence this may lead to miscalculation of funds and may lead to loss of funds , because if safetransferfrom()
 is called on a token address that doesn’t have contract in it, it will always return success, bypassing the return value check. Due to this protocol will think that funds have been transferred and successful , and records will be accordingly calculated, but in reality funds were never transferred.
So this will lead to miscalculation and possibly loss of funds
There are 2 instances of this issue
File: main/canto-namespace-protocol/src/Namespace.sol 114: SafeTransferLib.safeTransferFrom(note, msg.sender, revenueAddress, fusingCosts);
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol
File: main/canto-namespace-protocol/src/Tray.sol 157: Â SafeTransferLib.safeTransferFrom(note, msg.sender, revenueAddress, _amount * trayPrice);
Use openzeppelin’s safeERC20 or implement a code existence check.
There are 5 instances of this issue
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-bio-protocol/src/Bio.sol
File: main/canto-bio-protocol/src/Bio.sol 2: pragma solidity >=0.8.0;
File: main/canto-namespace-protocol/src/Namespace.sol 2: pragma solidity >=0.8.0;
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol
File: main/canto-namespace-protocol/src/Tray.sol 2: pragma solidity >=0.8.0;
File: main/canto-pfp-protocol/src/ProfilePicture.sol 2: pragma solidity >=0.8.0;
File: main/canto-namespace-protocol/src/Utils.sol 2: pragma solidity >=0.8.0;
#0 - 0xleastwood
2023-04-11T16:12:24Z
03 - These are mapping and not arrays so don't suffer from this issue.
#1 - 0xleastwood
2023-04-11T16:13:07Z
Some other issues are listed in known issues. _safeMint()
lack of usage is documented in the code.
#2 - c4-judge
2023-04-11T16:13:34Z
0xleastwood marked the issue as grade-b
🌟 Selected for report: 0xSmartContract
Also found by: 0xdaydream, 0xnev, Aymen0909, Deekshith99, Diana, EvanW, Fanz, JCN, Jerry0x, K42, Kresh, Madalad, MiniGlome, Polaris_tow, Rageur, ReyAdmirado, Rolezn, SAAJ, SaeedAlipoor01988, Sathish9098, Shubham, Udsen, Viktor_Cortess, Walter, anodaram, arialblack14, atharvasama, caspersolangii, codeslide, descharre, fatherOfBlocks, felipe, ginlee, igingu, lukris02, nadin, slvDev, tnevler, turvy_fuzz, viking71
12.034 USDC - $12.03
S No. | Issue | Instances | Gas Savings (from provided tests) |
---|---|---|---|
[G-01] | x += y costs more gas than x = x + y for state variables | 1 | 113 |
[G-02] | Usage of uints or ints smaller than 32 bytes incurs overhead | 6 | 168 |
Using the addition operator instead of plus-equals saves 113 gas.
There is 1 instance of this issue
File: main/canto-namespace-protocol/src/Namespace.sol 150: numBytes += numBytesChar;
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Each operation involving a uint8
 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8
) as compared to ones involving uint256
, due to the compiler having to clear the higher bits of the memory word before operating on the uint8
, as well as the associated stack operations of doing so. Use a larger size then downcast where needed
There are 6 instances of this issue:
File: main/canto-namespace-protocol/src/Namespace.sol 125: uint8 tileOffset = _characterList[i].tileOffset; 134: uint8 characterModifier = tileData.characterModifier;
https://github.com/code-423n4/2023-03-canto-identity/blob/main/canto-namespace-protocol/src/Tray.sol
File: main/canto-namespace-protocol/src/Tray.sol 195: function getTile(uint256 _trayId, uint8 _tileOffset) external view returns (TileData memory tileData) {
File: main/canto-namespace-protocol/src/Utils.sol 131:Â uint8 asciiStartingIndex = 97; 138: uint8 asciiStartingIndex = 97; 267: function _getUtfSequence(bytes memory _startingSequence, uint8 _characterIndex)
#0 - c4-judge
2023-04-11T04:19:08Z
0xleastwood marked the issue as grade-b