在UTC时间9月14日凌晨3点左右,我们平台的资金池遭到了破坏,导致在我们的合约在脱机前被盗了大约44,427.4302 EOS个EOS。 我们的EOSBETDICE11和EOSBETCASINO中剩余的463,745 EOS是安全的。 我们希望尽可能透明地解释这种违规行为并解答社区成员的任何担忧。
攻击事件复盘
受攻击的代码如下:
// extend from EOSIO_ABI, because we need to listen to incoming eosio.token transfers
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
auto self = receiver; \
if( action == N(onerror)) { \
/* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \
eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \
} \
if( code == self || code == N(eosio.token) || action == N(onerror) ) { \
TYPE thiscontract( self ); \
switch( action ) { \
EOSIO_API( TYPE, MEMBERS ) \
} \
/* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
} \
} \
}
这是一个ABI转发器,它允许我们的合同收听传入的eosio.token转移事件,以及与智能合约的正常交互(相当于标准ABI)。
这里显示了错误的代码:
if( code == self || code == N(eosio.token) || action == N(onerror) ) { \
如果主叫合同是eosio.token或者自我(即:eosbetdice11),或者如果该行为是来自eosio系统合同的错误,则该行将任何行动转发给ABI(以及内部合约函数)。
这是有缺陷的,因为它允许攻击者完全绕过eosio.token →传递函数,并直接调用eosbetdice11 → transfer。 攻击者正是这样做的,通过调用eosbetdice11 →传输正确的转移参数,他被允许下注而不将EOS转移到合同中。 如果输了,他没有得到任何报酬,但无须付出EOS。 然而,如果赢了,他就从合同中赢取了真正的EOS。
我们已经修改了这个ABI转发器如下:
// extend from EOSIO_ABI, because we need to listen to incoming eosio.token transfers
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
auto self = receiver; \
if( code == self || code == N(eosio.token)) { \
if( action == N(transfer)){ \
eosio_assert( code == N(eosio.token), "Must transfer EOS"); \
} \
TYPE thiscontract( self ); \
switch( action ) { \
EOSIO_API( TYPE, MEMBERS ) \
} \
/* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
} \
} \ }
我们执行了一些变更。 首先,我们完全删除了eosio → onerror功能,因为合同未使用它。 更重要的是,我们添加了此检查:
if( action == N(transfer)){ \
eosio_assert( code == N(eosio.token), "Must transfer EOS”); \
} \
这可确保过滤传入的传输操作,以便只将eosio.token传输转发到我们的其余合同。 如果调用eosbetdice11 → transfer,则此操作将失败,并且不会转发。
这个有缺陷的ABI转发器是第一个围绕社区和早期开发商流传的ABI转发器。 这个确切的转发代码已经烧毁了多个其他游戏和智能合约,这允许攻击者绕过eosio.token检查,并直接调用合同上的转账功能。
不忘初心 砥砺前行
我们非常重视EOSBet的安全性。我们的代码由我们的开发团队和多个独立的第三方进行了广泛的审核。尽管如此,我们的智能合约仍然存在漏洞。未来的任务是加强我们的安全实践,确保将来不会发生类似的事件。以下是我们加强安全措施的几种方法:
•更强大的内部代码测试和审核流程 — 随着我们的开发团队的扩展,这一过程变得更加容易。
•来自第三方的至少两次广泛的安全审核。我们正致力于识别这个领域的最佳开发人员和审计人员。
•更好的资金和智能合约监控,以便尽早发现资金的大幅下降,并将资金冻结在合同内,直到人工干预。
最后,经过另一次审核,我们将在几周内开源所有骰子智能合约代码。自我们成立以来,所有的骰子都已经证明是公平的。目前,统计分析证明了这一点,很快,我们的智能合约代码也将如此。
献给社区的一段话
我们很自豪能够成为第一个推动EOS极限并展示网络强大功能的应用程序。然而,作为EOS区块链中规模最大,交易量最多的应用,承受着很大的风险和责任。仅仅过了三个月,这个区块链仍然是个婴儿,在成长的过程中不可避免地会出现问题。
感谢我们的社区在此停机期间与我们联系,我们将BET空头比例从1:30增加到1:10,这意味着每下注10个EOS,玩家将获得1个BET代币。这将持续24小时,直到9月XX日的1:00AM UTC。
真诚的感谢
EOSBet团队