Skip to content

Commit

Permalink
Separate Vault from Avatar (#750)
Browse files Browse the repository at this point in the history
* Emit SendEther on GenericCall

* Separate Valut from Avatar

* Bump version
  • Loading branch information
ben-kaufman authored May 12, 2020
1 parent 32ae08d commit dc6dd31
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 40 deletions.
24 changes: 1 addition & 23 deletions contracts/controller/Avatar.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,12 @@ pragma solidity ^0.5.17;

import "@daostack/infra-experimental/contracts/Reputation.sol";
import "./DAOToken.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol";
import "./Vault.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/upgrades/contracts/Initializable.sol";


//Proxy contracts cannot recive eth via fallback function.
//For now , we will use this vault to overcome that
contract Vault is Ownable {
event ReceiveEther(address indexed _sender, uint256 _value);

/**
* @dev enables this contract to receive ethers
*/
function() external payable {
emit ReceiveEther(msg.sender, msg.value);
}

function sendEther(uint256 _amountInWei, address payable _to) external onlyOwner returns(bool) {
// solhint-disable-next-line avoid-call-value
(bool success, ) = _to.call.value(_amountInWei)("");
require(success, "sendEther failed.");
}
}


/**
* @title An Avatar holds tokens, reputation and ether for a controller
*/
Expand All @@ -41,7 +21,6 @@ contract Avatar is Initializable, Ownable {
mapping(string=>string) public db;

event GenericCall(address indexed _contract, bytes _data, uint _value, bool _success);
event SendEther(uint256 _amountInWei, address indexed _to);
event ExternalTokenTransfer(address indexed _externalToken, address indexed _to, uint256 _value);
event ExternalTokenTransferFrom(address indexed _externalToken, address _from, address _to, uint256 _value);
event ExternalTokenApproval(address indexed _externalToken, address _spender, uint256 _value);
Expand Down Expand Up @@ -104,7 +83,6 @@ contract Avatar is Initializable, Ownable {
*/
function sendEther(uint256 _amountInWei, address payable _to) external onlyOwner returns(bool) {
vault.sendEther(_amountInWei, _to);
emit SendEther(_amountInWei, _to);
return true;
}

Expand Down
25 changes: 25 additions & 0 deletions contracts/controller/Vault.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pragma solidity ^0.5.17;

import "@openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol";


//Proxy contracts cannot recive eth via fallback function.
//For now , we will use this vault to overcome that
contract Vault is Ownable {
event ReceiveEther(address indexed _sender, uint256 _value);
event SendEther(address indexed _to, uint256 _value);

/**
* @dev enables this contract to receive ethers
*/
function() external payable {
emit ReceiveEther(msg.sender, msg.value);
}

function sendEther(uint256 _amountInWei, address payable _to) external onlyOwner returns(bool) {
// solhint-disable-next-line avoid-call-value
(bool success, ) = _to.call.value(_amountInWei)("");
require(success, "sendEther failed.");
emit SendEther(_to, _amountInWei);
}
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@daostack/arc-experimental",
"version": "0.1.1-rc.18",
"version": "0.1.1-rc.19",
"description": "A platform for building DAOs",
"files": [
"contracts/",
Expand Down
12 changes: 10 additions & 2 deletions test/avatar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const helpers = require('./helpers');
const Avatar = artifacts.require("./Avatar.sol");
const Vault = artifacts.require("./Vault.sol");
const ERC20Mock = artifacts.require('./test/ERC20Mock.sol');
const ActionMock = artifacts.require('./test/ActionMock.sol');
const SchemeMock = artifacts.require('./test/SchemeMock.sol');
Expand Down Expand Up @@ -73,8 +74,15 @@ contract('Avatar', accounts => {
var avatarBalance = await web3.eth.getBalance(vault)/web3.utils.toWei('1', "ether");
assert.equal(avatarBalance,1);
var tx = await avatar.sendEther(web3.utils.toWei('1', "ether"),otherAvatar.address);
assert.equal(tx.logs.length, 1);
assert.equal(tx.logs[0].event, "SendEther");
var vaultContract = await Vault.at(vault);
await vaultContract.getPastEvents('SendEther', {
filter: {_addr: avatar.address}, // Using an array means OR: e.g. 20 or 23
fromBlock: tx.blockNumber,
toBlock: 'latest'
})
.then(function(events){
assert.equal(events[0].event,"SendEther");
});
avatarBalance =await web3.eth.getBalance(vault)/web3.utils.toWei('1', "ether");
assert.equal(avatarBalance,0);
var otherVault = await otherAvatar.vault();
Expand Down
27 changes: 14 additions & 13 deletions test/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const helpers = require('./helpers');
const Controller = artifacts.require("./Controller.sol");
const Reputation = artifacts.require("./Reputation.sol");
const Avatar = artifacts.require("./Avatar.sol");
const Vault = artifacts.require("./Vault.sol");
const DAOToken = artifacts.require("./DAOToken.sol");
const GlobalConstraintMock = artifacts.require('./test/GlobalConstraintMock.sol');
const ActionMock = artifacts.require('./test/ActionMock.sol');
Expand Down Expand Up @@ -407,16 +408,16 @@ contract('Controller', accounts => {
await web3.eth.sendTransaction({from:accounts[0],to:avatar.address, value: web3.utils.toWei('1', "ether")});
//send some ether from an organization's avatar to the otherAvatar
var tx = await controller.sendEther(web3.utils.toWei('1', "ether"),otherAvatar.address);
await avatar.getPastEvents('SendEther', {
var vault = await Vault.at(await avatar.vault());
await vault.getPastEvents('SendEther', {
filter: {_addr: avatar.address}, // Using an array means OR: e.g. 20 or 23
fromBlock: tx.blockNumber,
toBlock: 'latest'
})
.then(function(events){
assert.equal(events[0].event,"SendEther");
});
var vault = await avatar.vault();
var avatarBalance = await web3.eth.getBalance(vault)/web3.utils.toWei('1', "ether");
var avatarBalance = await web3.eth.getBalance(vault.address)/web3.utils.toWei('1', "ether");
assert.equal(avatarBalance, 0);
var otherVault = await otherAvatar.vault();
var otherAvatarBalance = await web3.eth.getBalance(otherVault)/web3.utils.toWei('1', "ether");
Expand Down Expand Up @@ -585,16 +586,16 @@ contract('Controller', accounts => {
var globalConstraintsCount =await controller.globalConstraintsCount();
assert.equal(globalConstraintsCount[0],0);
var tx = await controller.sendEther(web3.utils.toWei('1', "ether"),otherAvatar.address);
await avatar.getPastEvents('SendEther', {
filter: {_addr: avatar.address}, // Using an array means OR: e.g. 20 or 23
fromBlock: tx.blockNumber,
toBlock: 'latest'
})
.then(function(events){
assert.equal(events[0].event,"SendEther");
});
var vault = await avatar.vault();
var avatarBalance = await web3.eth.getBalance(vault)/web3.utils.toWei('1', "ether");
var vault = await Vault.at(await avatar.vault());
await vault.getPastEvents('SendEther', {
filter: {_addr: avatar.address}, // Using an array means OR: e.g. 20 or 23
fromBlock: tx.blockNumber,
toBlock: 'latest'
})
.then(function(events){
assert.equal(events[0].event,"SendEther");
});
var avatarBalance = await web3.eth.getBalance(vault.address)/web3.utils.toWei('1', "ether");
assert.equal(avatarBalance, 0);
var otherVault = await otherAvatar.vault();
var otherAvatarBalance = await web3.eth.getBalance(otherVault)/web3.utils.toWei('1', "ether");
Expand Down

0 comments on commit dc6dd31

Please sign in to comment.