fix reentrancy and reexecution

This commit is contained in:
Ricardo Guilherme Schmidt 2018-03-24 05:53:35 -03:00
parent 8a32a3ea47
commit cfb389398d
1 changed files with 21 additions and 39 deletions

View File

@ -14,12 +14,13 @@ contract Identity is ERC725, ERC735 {
mapping (bytes32 => uint256) indexes; mapping (bytes32 => uint256) indexes;
mapping (uint => Transaction) txx; mapping (uint => Transaction) txx;
mapping (uint256 => uint256) minimumApprovalsByKeyPurpose; mapping (uint256 => uint256) minimumApprovalsByKeyPurpose;
bytes32[] pendingTransactions;
uint nonce = 0; uint nonce = 0;
address recoveryContract; address recoveryContract;
address recoveryManager; address recoveryManager;
struct Transaction { struct Transaction {
bool valid;
address to; address to;
uint value; uint value;
bytes data; bytes data;
@ -455,6 +456,7 @@ contract Identity is ERC725, ERC735 {
executionId = nonce; executionId = nonce;
nonce++; nonce++;
txx[executionId] = Transaction({ txx[executionId] = Transaction({
valid: true,
to: _to, to: _to,
value: _value, value: _value,
data: _data, data: _data,
@ -473,29 +475,30 @@ contract Identity is ERC725, ERC735 {
returns(bool success) //(?) should return approved instead of success? returns(bool success) //(?) should return approved instead of success?
{ {
Transaction storage trx = txx[_id]; Transaction memory trx = txx[_id];
require(trx.valid);
uint256 requiredKeyPurpose = trx.to == address(this) ? MANAGEMENT_KEY : ACTION_KEY;
require(isKeyPurpose(_key, requiredKeyPurpose));
bytes32 keyHash = keccak256(_key, requiredKeyPurpose);
require(txx[_id].approvals[keyHash] != _approval);
uint256 approvalCount; if (_approval) {
uint256 requiredKeyPurpose; trx.approverCount++;
if (trx.to == address(this)) {
require(isKeyPurpose(_key, MANAGEMENT_KEY));
bytes32 managerKeyHash = keccak256(_key, MANAGEMENT_KEY);
requiredKeyPurpose = MANAGEMENT_KEY;
approvalCount = _calculateApprovals(managerKeyHash, _approval, trx);
} else { } else {
require(isKeyPurpose(_key, ACTION_KEY)); trx.approverCount--;
bytes32 actorKeyHash = keccak256(_key, ACTION_KEY);
requiredKeyPurpose = ACTION_KEY;
approvalCount = _calculateApprovals(actorKeyHash, _approval, trx);
} }
emit Approved(_id, _approval); emit Approved(_id, _approval);
if (approvalCount >= minimumApprovalsByKeyPurpose[requiredKeyPurpose]) { if (trx.approverCount < minimumApprovalsByKeyPurpose[requiredKeyPurpose]) {
txx[_id].approvals[keyHash] = _approval;
txx[_id] = trx;
} else {
delete txx[_id];
//(?) success should be included in event? //(?) success should be included in event?
success = trx.to.call.value(trx.value)(trx.data); success = address(trx.to).call.value(trx.value)(trx.data);
emit Executed(_id, trx.to, trx.value, trx.data); emit Executed(_id, trx.to, trx.value, trx.data);
} }
} }
@ -545,27 +548,6 @@ contract Identity is ERC725, ERC735 {
emit KeyRemoved(myKey.key, myKey.purpose, myKey.keyType); emit KeyRemoved(myKey.key, myKey.purpose, myKey.keyType);
} }
function _calculateApprovals(
bytes32 _keyHash,
bool _approval,
Transaction storage trx
)
private
returns (uint256 approvalCount)
{
require(trx.approvals[_keyHash] != _approval);
trx.approvals[_keyHash] = _approval;
if (_approval) {
trx.approverCount++;
} else {
trx.approverCount--;
}
return trx.approverCount;
}
function _includeClaim( function _includeClaim(
bytes32 _claimHash, bytes32 _claimHash,
uint256 _claimType, uint256 _claimType,