Skip to content
Permalink
Browse files

Merge branch 'beta_test_remove_ethertoken' of github.com:aragon/arago…

…n-apps into good-vault
  • Loading branch information...
izqui committed Mar 18, 2018
2 parents ef13ad5 + d8dac5a commit 42c954df035c0513fbbc6befae86a2047f5a635c
@@ -2,6 +2,7 @@ const { assertRevert, assertInvalidOpcode } = require('@aragon/test-helpers/asse
const getBalance = require('@aragon/test-helpers/balance')(web3)

const Vault = artifacts.require('Vault')
const ERC20Connector = artifacts.require('ERC20Connector')
const ETHConnector = artifacts.require('ETHConnector')
const Finance = artifacts.require('FinanceMock')
const MiniMeToken = artifacts.require('MiniMeToken')
@@ -17,6 +18,10 @@ contract('Finance App', accounts => {

beforeEach(async () => {
vault = await Vault.new()
const ethConnector = await ETHConnector.new()
const erc20Connector = await ERC20Connector.new()
await vault.initialize(erc20Connector.address, ethConnector.address)


token1 = await MiniMeToken.new(n, n, 0, 'n', 0, 'n', true) // dummy parameters for minime
await token1.generateTokens(vault.address, 100)
@@ -11,6 +11,7 @@ interface IVaultConnector {
event Deposit(address indexed token, address indexed sender, uint256 amount);
}


contract IVaultFake {
function IVaultFake() public {
// work around coverage weird error
@@ -1,7 +1,6 @@
pragma solidity 0.4.18;

import "./VaultBase.sol"; // split made to avoid circular import
import "./IVaultConnector.sol";

import "./connectors/ERC20Connector.sol";
import "./connectors/ETHConnector.sol";
@@ -10,15 +9,6 @@ import "@aragon/os/contracts/lib/misc/Migrations.sol";


contract Vault is VaultBase {
address constant ETH = address(0);
uint32 constant ERC165 = 165;
uint32 constant NO_DETECTION = uint32(-1);

// connectors can define their own extra roles, challenge for discoverability
bytes32 constant REGISTER_TOKEN_STANDARD = keccak256("REGISTER_TOKEN_STANDARD");
bytes32 constant TRANSFER_ROLE = keccak256("TRANSFER_ROLE");
// TODO: Abstract over different APPROVAL and have just one role?

struct TokenStandard {
uint32 erc;
uint32 interfaceDetectionERC;
@@ -28,31 +18,37 @@ contract Vault is VaultBase {

TokenStandard[] public standards;
mapping (address => address) public connectors;
uint32[] public supportedInterfaceDetectionERCs;

ERC20Connector public erc20ConnectorBase;
ETHConnector public ethConnectorBase;
mapping(uint32 => bool) public supportedInterfaceDetectionERCs;

event NewTokenStandard(uint32 indexed erc, uint32 indexed interfaceDetectionERC, bytes4 indexed interfaceID, address connector);

function Vault() public {
// TODO Role??
function initializeConnectors() public {
// this allows to simplify template logic, as they don't have to deploy this
erc20ConnectorBase = new ERC20Connector();
ethConnectorBase = new ETHConnector();
_setConnectors(new ERC20Connector(), new ETHConnector());
}

function initializeEmpty() onlyInit public {
initialized();

initialize(erc20ConnectorBase, ethConnectorBase);
supportedInterfaceDetectionERCs[NO_DETECTION] = true;
supportedInterfaceDetectionERCs[ERC165] = true;
}

function initialize(ERC20Connector erc20Connector, ETHConnector ethConnector) onlyInit public {
initialized();
initializeEmpty();

supportedInterfaceDetectionERCs.push(NO_DETECTION);
supportedInterfaceDetectionERCs.push(ERC165);
_setConnectors(erc20Connector, ethConnector);
}

function _setConnectors(ERC20Connector erc20Connector, ETHConnector ethConnector) internal {
// register erc20 as the first standard
_registerStandard(20, NO_DETECTION, bytes4(0), erc20Connector);
if (erc20Connector != address(0))
_registerStandard(20, NO_DETECTION, bytes4(0), erc20Connector);
// directly manage ETH with the ethConnector
connectors[ETH] = ethConnector;
if (ethConnector != address(0))
connectors[ETH] = ethConnector;

}

function () payable public {
@@ -102,13 +98,7 @@ contract Vault is VaultBase {
}

function isInterfaceDetectionERCSupported(uint32 interfaceDetectionERC) public view returns (bool) {
for (uint j = 0; j < supportedInterfaceDetectionERCs.length; j++) {
if (supportedInterfaceDetectionERCs[j] == interfaceDetectionERC) {
return true;
}
}

return false;
return supportedInterfaceDetectionERCs[interfaceDetectionERC];
}

function _registerStandard(uint32 erc, uint32 interfaceDetectionERC, bytes4 interfaceID, address connector) internal {
@@ -3,6 +3,7 @@ pragma solidity 0.4.18;
import "../VaultBase.sol";
import "@aragon/os/contracts/lib/zeppelin/token/ERC20.sol";


contract ERC20Connector is VaultBase, IVaultConnector {
function deposit(address token, address who, uint256 value, bytes how) payable external returns (bool) {
require(how.length == 0); // sending data is not supported in ERC20
@@ -112,6 +112,7 @@ interface ERC721TokenReceiver {
function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
}


contract ERC721Fake {
function ERC721Fake() public {
// work around coverage weird error
@@ -1,5 +1,7 @@
pragma solidity ^0.4.18;

import "@aragon/os/contracts/lib/minime/MiniMeToken.sol";
import "../../detectors/standards/ERC165.sol";

interface ERC777 {
function name() public constant returns (string);
@@ -33,8 +35,48 @@ interface ERC777TokensRecipient {
function tokensReceived(address operator, address from, address to, uint amount, bytes userData, bytes operatorData) public;
}

contract ERC777Fake {
function ERC777Fake() public {
// work around coverage weird error

contract ERC777Token is MiniMeToken, ERC165 {
function granularity() public constant returns (uint256) {
// TODO
}

function send(address to, uint256 amount) public {
// TODO
}

function send(address to, uint256 amount, bytes userData) public {
// TODO
}

function authorizeOperator(address operator) public {
// TODO
}

function revokeOperator(address operator) public {
// TODO
}

function isOperatorFor(address operator, address tokenHolder) public constant returns (bool) {
// TODO
}

function operatorSend(address from, address to, uint256 amount, bytes userData, bytes operatorData) public {
// TODO
}

function supportsInterface(bytes4 interfaceID) external view returns (bool) {
return
interfaceID == this.supportsInterface.selector || // ERC165
interfaceID == this.name.selector
^ this.symbol.selector
^ this.totalSupply.selector
^ this.granularity.selector
^ this.balanceOf.selector
// TODO! ^ this.send.selector
^ this.authorizeOperator.selector
^ this.revokeOperator.selector
^ this.isOperatorFor.selector
^ this.operatorSend.selector;
}
}
@@ -11,6 +11,7 @@ interface ERC165 {
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}


contract ERC165Fake {
function ERC165Fake() public {
// work around coverage weird error
@@ -8,6 +8,7 @@ interface ERC780 {
function removeClaim(address issuer, address subject, bytes32 key) public;
}


contract ERC780Fake {
function ERC780Fake() public {
// work around coverage weird error
@@ -10,6 +10,9 @@ import "truffle/Assert.sol";
contract TestVault {
MiniMeToken token;

ERC20Connector erc20Connector = new ERC20Connector();
ETHConnector ethConnector = new ETHConnector();

IVaultConnector vault;

uint constant public initialBalance = 200 wei;
@@ -23,6 +26,7 @@ contract TestVault {

function beforeEach() {
vault = IVaultConnector(new Vault());
Vault(vault).initialize(erc20Connector, ethConnector);
}

function testETHDeposit() {
@@ -45,7 +49,6 @@ contract TestVault {
Assert.equal(address(10).balance, 1, "should hold 1 wei");
}

/*
// For some reason uncommenting this code makes truffle OOG...
function testTokenDeposit() {
token.approve(vault, 1);
@@ -54,7 +57,6 @@ contract TestVault {
Assert.equal(token.balanceOf(vault), 1, "should hold 1 token");
Assert.equal(vault.balance(token), 1, "should return 1 token balance");
}
*/

function testTransferTokens() {
address to = address(1);
@@ -1,6 +1,95 @@
const { assertRevert, assertInvalidOpcode } = require('@aragon/test-helpers/assertThrow')
const getBalance = require('@aragon/test-helpers/balance')(web3)

const Vault = artifacts.require('Vault')
const IVaultConnector = artifacts.require('IVaultConnector')

const MiniMeToken = artifacts.require('@aragon/os/contracts/lib/minime/MiniMeToken')

const getContract = name => artifacts.require(name)

const NULL_ADDRESS = '0x00'

contract('Vault app', (accounts) => {})
contract('Vault app', (accounts) => {
let vaultBase, vault, token, token777

const ETH = '0x0'
const ERC165 = 165
const NO_DETECTION = 2**32 - 1

before(async () => {
token = await MiniMeToken.new(NULL_ADDRESS, NULL_ADDRESS, 0, 'N', 0, 'N', true)
await token.generateTokens(accounts[0], 200)

token777 = await getContract('ERC777').new(NULL_ADDRESS, NULL_ADDRESS, 0, 'N', 0, 'N', true)
await token777.generateTokens(accounts[0], 200)
})

beforeEach(async () => {
vaultBase = await Vault.new()
vault = IVaultConnector.at(vaultBase.address)
await vaultBase.initializeEmpty()
await vaultBase.initializeConnectors()
//
await vaultBase
})

context('Deposits and transfers', async() => {
it('deposits ETH', async() => {
await vault.deposit(ETH, accounts[0], 1, [0], { value: 1 })
assert.equal((await getBalance(vault.address)).toString(), 1, "should hold 1 wei")
assert.equal((await vault.balance(ETH)).toString(), 1, "should return 1 wei balance")
})

it('deposits ETH trhough callback', async() => {
await vault.sendTransaction( { value: 1 })
assert.equal((await getBalance(vault.address)).toString(), 1, "should hold 1 wei")
})
})

context('Standards', async() => {
let erc20Connector, erc777Connector

before(async() => {
erc20Connector = await getContract('ERC20Connector').new()
erc777Connector = await getContract('ERC777Connector').new()
})

it('registers standard', async() => {
await vaultBase.registerStandard(777, ERC165, ["0x01", "0x02", "0x03", "0x04"], erc20Connector.address)
})

it('detects standard (no standard)', async() => {
let ts = await vaultBase.detectTokenStandard(token.address)
assert.equal(ts.toString(), 0, "standard ID should be 0")
})

it('detects standard', async() => {
let ts = await vaultBase.detectTokenStandard(token777.address)
assert.equal(ts.toString(), 0, "standard ID should be 1")
})

it('fails trying to register standard again', async() => {
return assertRevert(async() => {
await vaultBase.registerStandard(20, ERC165, ["0x01", "0x02", "0x03", "0x04"], erc20Connector.address)
})
})

it('token conforms to standard', async() => {
assert.isTrue(await vaultBase.conformsToStandard(token.address, ERC165), "should return false")
})

it('token doesn\'t conform to standard (ERC165)', async() => {
assert.isFalse(await vaultBase.conformsToStandard(token777.address, 165), "should return false")
})

it('fails checking ERC20 against ERC165', async() => {
return assertRevert(async() => {
await vaultBase.conformsToStandard(token.address, 165)
})
})
it('token doesn\'t conform to standard (not ERC165)', async() => {
assert.isFalse(await vaultBase.conformsToStandard(token.address, 0), "should return false")
})
})
})
@@ -10,6 +10,8 @@ import "@aragon/id/contracts/IFIFSResolvingRegistrar.sol";

import "@aragon/apps-voting/contracts/Voting.sol";
import "@aragon/apps-vault/contracts/Vault.sol";
//import "@aragon/apps-vault/contracts/connectors/ETHConnector.sol";
//import "@aragon/apps-vault/contracts/connectors/ERC20Connector.sol";
import "@aragon/apps-token-manager/contracts/TokenManager.sol";
import "@aragon/apps-finance/contracts/Finance.sol";

@@ -102,7 +104,9 @@ contract BetaTemplateBase {
}

// inits
vault.initialize(vault.erc20ConnectorBase(), vault.ethConnectorBase()); // init with trusted connectors
//vault.initialize(vault.erc20ConnectorBase(), vault.ethConnectorBase()); // init with trusted connectors
vault.initializeEmpty();
//vault.initializeConnectors(); // TODO: it doesn't work... out of gas?
finance.initialize(IVaultConnector(vault), uint64(-1) - uint64(now)); // yuge period

// clean-up
Oops, something went wrong.

0 comments on commit 42c954d

Please sign in to comment.
You can’t perform that action at this time.