Alpaca项目评估报告

https://defisafety.com/2021/06/11/alpaca-finance-bsc/

项目安全评估结果

Alpaca Finance项目合约审计完善、代码开源,策略基本透明;虽然有一些审计的问题并未部署到生产环境,但是如果不做借贷是比较安全的。

并且Alpaca Finance项目的AlpacaToken代币是随着区块的增加而铸造的,因此不会出现像AutoShark那样被闪电贷攻击铸造很多SHARK代币。

评估维度 评估结果
审计报告 合约代码由多家审计公司审计,发现的严重问题基本修复,未修复的问题也不影响非借贷类使用者。
智能合约 完全开源,部署的智能合约与审计修复后的智能合约代码基本一致;
其中有一个DebtToken合约在授信转账后未更新授信额度的问题部署的合约与源码不一致,但是如果不做借贷进行farm并且不授权给其他地址则没有问题。
安全漏洞 未发现合约后门。
AlpacaToken有一个owner可以锁定的方法,但是被锁定的地址可以通过调用解锁方法来释放;所以不能让合约持有AlpacaToken,不然被锁定了就提不出来了;这可能也是Alpaca团队预防被合约攻击的一种手段
资金投向 存入的资金在本平台被其他人借出并最终投向了pancakeswapwault.finance

审计报告

Alpaca主项目共有两个审计公司做了代码审计,分别如下:

Alpaca的Grazing Range 合约也有两个审计公司做了代码审计,分别如下:

审计报告分析

  1. 由多家审计公司进行审计是加分项

  2. 审计报告中发现的严重级别的问题都已经修正

合约代码

是否开源

合约代码开源,并在官方文档提供代码链接bsc-alpaca-contract

合约代码检查

GrazingRange.sol合约

审计报告提供的fix后的源码

image-20210616125519806

image-20210616125857105

部署的智能合约GrazingRange的代码,也是修复后的代码

image-20210616125337941

AlpacaToken合约

  • ATC-03 | Lack of State Update in已经修复
审计报告

image-20210616142028325

合约源码
1
2
3
4
5
6
7

function manualMint(address _to, uint256 _amount) public onlyOwner {
require(manualMinted.add(_amount) <= MANUAL_MINT_LIMIT, "mint limit exceeded");
manualMinted = manualMinted.add(_amount);
mint(_to, _amount);
}

DebtToken合约

DTC-01 | Lack of Allowance Check In 源码已经修复,但是生产环境部署的是未修复代码;

此问题如果有影响必须满足两个条件:

  1. A地址参与此项目的借贷farm
  2. A地址把获取到的debttoken授信一部分给其他地址B

满足以上两个条件之后获得授信的地址B就可以转移所有的A的debttoken。

审计报告问题

image-20210616143105352

合约源码
1
2
3
4
5
6
7
8

function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
require(okHolders[from], "debtToken::transferFrom:: unapproved holder in from");
require(okHolders[to], "debtToken::transferFrom:: unapproved holder in to");
_transfer(from, to, amount);
_approve(from, _msgSender(), allowance(from, _msgSender()).sub(amount, "BEP20: transfer amount exceeds allowance"));
return true;
}
线上部署合约代码DebtToken
1
2
3
4
5
6
7

function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
require(okHolders[from], "debtToken::transferFrom:: unapproved holder in from");
require(okHolders[to], "debtToken::transferFrom:: unapproved holder in to");
_transfer(from, to, amount);
return true;
}

Vault合约

PeckShield审计报告的3.1Possible Drain of Vault Funds With Double Returns Of Excess Tokens问题

合约源码

![image-20210616145054787](/Users/apple/Library/Application Support/typora-user-images/image-20210616145054787.png)

生产环境部署的合约代码,其他代码与源码不完全一致,但是此问题已经修复

image-20210616145433604

PeckShield审计报告的3.4 Proper Leftover Return After Liquidation问题

此问题是在清算时剩余的金额没有返还给用户,而是给了清算人。

审计报告提供的问题代码:

image-20210616145742478

合约源码

image-20210616145813461

生产环境部署的代码

image-20210616145849931

安全漏洞

检查合约如下,均未发现明显的管理员或owner有权利转移别人资产的方法:

  • GrazingRange
  • WaultSwapWorker
  • AlpacaToken
  • PancakeswapV2Worker
  • Vault

AlpacaToken代码检查

AlpacaToken中有一个只允许owner调用的可以锁住任何人资产的方法,但是提供了unlock方法,被锁住的地址可以调用解锁。

此方法是一个小风险,虽然资产没有被转移还能由自己解锁,但是尚不清楚为什么要给owner锁住某个地址的资产的权限。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

function lock(address _account, uint256 _amount) external onlyOwner {
require(_account != address(0), "no lock to address(0)");
require(_amount <= balanceOf(_account), "no lock over balance");

_transfer(_account, address(this), _amount);

_locks[_account] = _locks[_account].add(_amount);
_totalLock = _totalLock.add(_amount);

if (_lastUnlockBlock[_account] < startReleaseBlock) {
_lastUnlockBlock[_account] = startReleaseBlock;
}

emit Lock(_account, _amount);
}


function unlock() external {
require(_locks[msg.sender] > 0, "no locked ALPACAs");

uint256 amount = canUnlockAmount(msg.sender);

_transfer(address(this), msg.sender, amount);
_locks[msg.sender] = _locks[msg.sender].sub(amount);
_lastUnlockBlock[msg.sender] = block.number;
_totalLock = _totalLock.sub(amount);
}