When to audit?
Security audits were created to help teams with great financial responsibility protect against known vulnerabilities and apply best practices in their smart contracts that would make them more robust and less error prone.
The truth is that security audits nowadays are being held as a flag to holders, to imply the whole project is secure and the team is reliable. This is the first myth that needs to be debunked. Many teams are taking advantage of these flags and using them inappropriately, leaving a big part of their projects' codebase unaudited. Others, spend money auditing already audited code just to have that stamp glowing on their marketing pages.
Intention needs to be clear before deciding what to audit in this project.
The UNT token smart contract
The entire contract code is this:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract UNT is ERC20 {
constructor() ERC20("UNT", "UNT") {
_mint(msg.sender, 12000000 * 10 ** decimals());
}
}
If you trim away licensing and compiler version, all you're left with is a class definition and a constructor with a single statement:
_mint(msg.sender, 12000000 * 10 ** decimals());
The rest of the contract's functionality is guaranteed by inheriting the ERC20 standard implementation of OpenZeppelin, a contract which has been audited and used countless times. The single statement makes this a fixed supply ERC20 token, since there is no way (in the ERC20 standard used) of calling "mint" from outside the contract. And because this statement is inside the constructor, it can only be called once, at the exact moment of contract deployment. There is no real reason for this contract to be audited.
The Migration smart contract
Is a single function contract which uses an audited standard implementation (OpenZeppelin ERC20) to transfer funds:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract TokenSwap {
using SafeMath for uint256;
uint256 public _arrayLimit = 250;
event MultiSend(uint256 total, address tokenAddress);
function multiSendERC20(address[] calldata receivers, uint256[] calldata amounts, address token) external {
require(receivers.length == amounts.length, "Each receiver address must have exactly one correspondent amount to be sent");
require(receivers.length < _arrayLimit, "The given address list exceeds allowed size");
ERC20 _token = ERC20(token);
uint256 total = 0;
for (uint256 i=0; i<receivers.length; i++) {
_token.transferFrom(msg.sender, receivers[i], amounts[i]);
total += amounts[i];
}
emit MultiSend(total, token);
}
}
It is also important to note that, once the migration process is over, this contract will never hold funds again. Furthermore, during the period it will be holding UNT tokens, the UNT token will be valueless because there will be no pool on UniSwap yet and the project will be just starting. So, in a way, there isn't a great security concern here as well.
When to audit?
Security audits were created to help teams with great financial responsibility protect against known vulnerabilities and apply best practices in their smart contracts that would make them more robust and less error prone.
The truth is that security audits nowadays are being held as a flag to holders, to imply the whole project is secure and the team is reliable. This is the first myth that needs to be debunked. Many teams are taking advantage of these flags and using them inappropriately, leaving a big part of their projects' codebase unaudited. Others, spend money auditing already audited code just to have that stamp glowing on their marketing pages.
Intention needs to be clear before deciding what to audit in this project.
The UNT token smart contract
The entire contract code is this:
If you trim away licensing and compiler version, all you're left with is a class definition and a constructor with a single statement:
_mint(msg.sender, 12000000 * 10 ** decimals());The rest of the contract's functionality is guaranteed by inheriting the ERC20 standard implementation of OpenZeppelin, a contract which has been audited and used countless times. The single statement makes this a fixed supply ERC20 token, since there is no way (in the ERC20 standard used) of calling "mint" from outside the contract. And because this statement is inside the constructor, it can only be called once, at the exact moment of contract deployment. There is no real reason for this contract to be audited.
The Migration smart contract
Is a single function contract which uses an audited standard implementation (OpenZeppelin ERC20) to transfer funds:
It is also important to note that, once the migration process is over, this contract will never hold funds again. Furthermore, during the period it will be holding UNT tokens, the UNT token will be valueless because there will be no pool on UniSwap yet and the project will be just starting. So, in a way, there isn't a great security concern here as well.