aboutsummaryrefslogtreecommitdiffstats
path: root/test/compilationTests/zeppelin/ownership
diff options
context:
space:
mode:
Diffstat (limited to 'test/compilationTests/zeppelin/ownership')
-rw-r--r--test/compilationTests/zeppelin/ownership/Claimable.sol40
-rw-r--r--test/compilationTests/zeppelin/ownership/Contactable.sol21
-rw-r--r--test/compilationTests/zeppelin/ownership/DelayedClaimable.sol43
-rw-r--r--test/compilationTests/zeppelin/ownership/HasNoContracts.sol21
-rw-r--r--test/compilationTests/zeppelin/ownership/HasNoEther.sol44
-rw-r--r--test/compilationTests/zeppelin/ownership/HasNoTokens.sol34
-rw-r--r--test/compilationTests/zeppelin/ownership/Multisig.sol28
-rw-r--r--test/compilationTests/zeppelin/ownership/NoOwner.sol14
-rw-r--r--test/compilationTests/zeppelin/ownership/Ownable.sol43
-rw-r--r--test/compilationTests/zeppelin/ownership/Shareable.sol189
10 files changed, 477 insertions, 0 deletions
diff --git a/test/compilationTests/zeppelin/ownership/Claimable.sol b/test/compilationTests/zeppelin/ownership/Claimable.sol
new file mode 100644
index 00000000..d063502d
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/Claimable.sol
@@ -0,0 +1,40 @@
+pragma solidity ^0.4.11;
+
+
+import './Ownable.sol';
+
+
+/**
+ * @title Claimable
+ * @dev Extension for the Ownable contract, where the ownership needs to be claimed.
+ * This allows the new owner to accept the transfer.
+ */
+contract Claimable is Ownable {
+ address public pendingOwner;
+
+ /**
+ * @dev Modifier throws if called by any account other than the pendingOwner.
+ */
+ modifier onlyPendingOwner() {
+ if (msg.sender != pendingOwner) {
+ throw;
+ }
+ _;
+ }
+
+ /**
+ * @dev Allows the current owner to set the pendingOwner address.
+ * @param newOwner The address to transfer ownership to.
+ */
+ function transferOwnership(address newOwner) onlyOwner {
+ pendingOwner = newOwner;
+ }
+
+ /**
+ * @dev Allows the pendingOwner address to finalize the transfer.
+ */
+ function claimOwnership() onlyPendingOwner {
+ owner = pendingOwner;
+ pendingOwner = 0x0;
+ }
+}
diff --git a/test/compilationTests/zeppelin/ownership/Contactable.sol b/test/compilationTests/zeppelin/ownership/Contactable.sol
new file mode 100644
index 00000000..0db3ee07
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/Contactable.sol
@@ -0,0 +1,21 @@
+pragma solidity ^0.4.11;
+
+import './Ownable.sol';
+
+/**
+ * @title Contactable token
+ * @dev Basic version of a contactable contract, allowing the owner to provide a string with their
+ * contact information.
+ */
+contract Contactable is Ownable{
+
+ string public contactInformation;
+
+ /**
+ * @dev Allows the owner to set a string with their contact information.
+ * @param info The contact information to attach to the contract.
+ */
+ function setContactInformation(string info) onlyOwner{
+ contactInformation = info;
+ }
+}
diff --git a/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol b/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol
new file mode 100644
index 00000000..f5fee614
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/DelayedClaimable.sol
@@ -0,0 +1,43 @@
+pragma solidity ^0.4.11;
+
+
+import './Claimable.sol';
+
+
+/**
+ * @title DelayedClaimable
+ * @dev Extension for the Claimable contract, where the ownership needs to be claimed before/after
+ * a certain block number.
+ */
+contract DelayedClaimable is Claimable {
+
+ uint256 public end;
+ uint256 public start;
+
+ /**
+ * @dev Used to specify the time period during which a pending
+ * owner can claim ownership.
+ * @param _start The earliest time ownership can be claimed.
+ * @param _end The latest time ownership can be claimed.
+ */
+ function setLimits(uint256 _start, uint256 _end) onlyOwner {
+ if (_start > _end)
+ throw;
+ end = _end;
+ start = _start;
+ }
+
+
+ /**
+ * @dev Allows the pendingOwner address to finalize the transfer, as long as it is called within
+ * the specified start and end time.
+ */
+ function claimOwnership() onlyPendingOwner {
+ if ((block.number > end) || (block.number < start))
+ throw;
+ owner = pendingOwner;
+ pendingOwner = 0x0;
+ end = 0;
+ }
+
+}
diff --git a/test/compilationTests/zeppelin/ownership/HasNoContracts.sol b/test/compilationTests/zeppelin/ownership/HasNoContracts.sol
new file mode 100644
index 00000000..b5bd649d
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/HasNoContracts.sol
@@ -0,0 +1,21 @@
+pragma solidity ^0.4.11;
+
+import "./Ownable.sol";
+
+/**
+ * @title Contracts that should not own Contracts
+ * @author Remco Bloemen <remco@2π.com>
+ * @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner
+ * of this contract to reclaim ownership of the contracts.
+ */
+contract HasNoContracts is Ownable {
+
+ /**
+ * @dev Reclaim ownership of Ownable contracts
+ * @param contractAddr The address of the Ownable to be reclaimed.
+ */
+ function reclaimContract(address contractAddr) external onlyOwner {
+ Ownable contractInst = Ownable(contractAddr);
+ contractInst.transferOwnership(owner);
+ }
+}
diff --git a/test/compilationTests/zeppelin/ownership/HasNoEther.sol b/test/compilationTests/zeppelin/ownership/HasNoEther.sol
new file mode 100644
index 00000000..2bcaf1b8
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/HasNoEther.sol
@@ -0,0 +1,44 @@
+pragma solidity ^0.4.11;
+
+import "./Ownable.sol";
+
+/**
+ * @title Contracts that should not own Ether
+ * @author Remco Bloemen <remco@2π.com>
+ * @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up
+ * in the contract, it will allow the owner to reclaim this ether.
+ * @notice Ether can still be send to this contract by:
+ * calling functions labeled `payable`
+ * `selfdestruct(contract_address)`
+ * mining directly to the contract address
+*/
+contract HasNoEther is Ownable {
+
+ /**
+ * @dev Constructor that rejects incoming Ether
+ * @dev The `payable` flag is added so we can access `msg.value` without compiler warning. If we
+ * leave out payable, then Solidity will allow inheriting contracts to implement a payable
+ * constructor. By doing it this way we prevent a payable constructor from working. Alternatively
+ * we could use assembly to access msg.value.
+ */
+ function HasNoEther() payable {
+ if(msg.value > 0) {
+ throw;
+ }
+ }
+
+ /**
+ * @dev Disallows direct send by settings a default function without the `payable` flag.
+ */
+ function() external {
+ }
+
+ /**
+ * @dev Transfer all Ether held by the contract to the owner.
+ */
+ function reclaimEther() external onlyOwner {
+ if(!owner.send(this.balance)) {
+ throw;
+ }
+ }
+}
diff --git a/test/compilationTests/zeppelin/ownership/HasNoTokens.sol b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
new file mode 100644
index 00000000..d1dc4b3e
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/HasNoTokens.sol
@@ -0,0 +1,34 @@
+pragma solidity ^0.4.11;
+
+import "./Ownable.sol";
+import "../token/ERC20Basic.sol";
+
+/**
+ * @title Contracts that should not own Tokens
+ * @author Remco Bloemen <remco@2π.com>
+ * @dev This blocks incoming ERC23 tokens to prevent accidental loss of tokens.
+ * Should tokens (any ERC20Basic compatible) end up in the contract, it allows the
+ * owner to reclaim the tokens.
+ */
+contract HasNoTokens is Ownable {
+
+ /**
+ * @dev Reject all ERC23 compatible tokens
+ * @param from_ address The address that is transferring the tokens
+ * @param value_ uint256 the amount of the specified token
+ * @param data_ Bytes The data passed from the caller.
+ */
+ function tokenFallback(address from_, uint256 value_, bytes data_) external {
+ throw;
+ }
+
+ /**
+ * @dev Reclaim all ERC20Basic compatible tokens
+ * @param tokenAddr address The address of the token contract
+ */
+ function reclaimToken(address tokenAddr) external onlyOwner {
+ ERC20Basic tokenInst = ERC20Basic(tokenAddr);
+ uint256 balance = tokenInst.balanceOf(this);
+ tokenInst.transfer(owner, balance);
+ }
+}
diff --git a/test/compilationTests/zeppelin/ownership/Multisig.sol b/test/compilationTests/zeppelin/ownership/Multisig.sol
new file mode 100644
index 00000000..76c78411
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/Multisig.sol
@@ -0,0 +1,28 @@
+pragma solidity ^0.4.11;
+
+
+/**
+ * @title Multisig
+ * @dev Interface contract for multisig proxy contracts; see below for docs.
+ */
+contract Multisig {
+ // EVENTS
+
+ // logged events:
+ // Funds has arrived into the wallet (record how much).
+ event Deposit(address _from, uint256 value);
+ // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
+ event SingleTransact(address owner, uint256 value, address to, bytes data);
+ // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
+ event MultiTransact(address owner, bytes32 operation, uint256 value, address to, bytes data);
+ // Confirmation still needed for a transaction.
+ event ConfirmationNeeded(bytes32 operation, address initiator, uint256 value, address to, bytes data);
+
+
+ // FUNCTIONS
+
+ // TODO: document
+ function changeOwner(address _from, address _to) external;
+ function execute(address _to, uint256 _value, bytes _data) external returns (bytes32);
+ function confirm(bytes32 _h) returns (bool);
+}
diff --git a/test/compilationTests/zeppelin/ownership/NoOwner.sol b/test/compilationTests/zeppelin/ownership/NoOwner.sol
new file mode 100644
index 00000000..7215abf3
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/NoOwner.sol
@@ -0,0 +1,14 @@
+pragma solidity ^0.4.11;
+
+import "./HasNoEther.sol";
+import "./HasNoTokens.sol";
+import "./HasNoContracts.sol";
+
+/**
+ * @title Base contract for contracts that should not own things.
+ * @author Remco Bloemen <remco@2π.com>
+ * @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or
+ * Owned contracts. See respective base contracts for details.
+ */
+contract NoOwner is HasNoEther, HasNoTokens, HasNoContracts {
+}
diff --git a/test/compilationTests/zeppelin/ownership/Ownable.sol b/test/compilationTests/zeppelin/ownership/Ownable.sol
new file mode 100644
index 00000000..f1628454
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/Ownable.sol
@@ -0,0 +1,43 @@
+pragma solidity ^0.4.11;
+
+
+/**
+ * @title Ownable
+ * @dev The Ownable contract has an owner address, and provides basic authorization control
+ * functions, this simplifies the implementation of "user permissions".
+ */
+contract Ownable {
+ address public owner;
+
+
+ /**
+ * @dev The Ownable constructor sets the original `owner` of the contract to the sender
+ * account.
+ */
+ function Ownable() {
+ owner = msg.sender;
+ }
+
+
+ /**
+ * @dev Throws if called by any account other than the owner.
+ */
+ modifier onlyOwner() {
+ if (msg.sender != owner) {
+ throw;
+ }
+ _;
+ }
+
+
+ /**
+ * @dev Allows the current owner to transfer control of the contract to a newOwner.
+ * @param newOwner The address to transfer ownership to.
+ */
+ function transferOwnership(address newOwner) onlyOwner {
+ if (newOwner != address(0)) {
+ owner = newOwner;
+ }
+ }
+
+}
diff --git a/test/compilationTests/zeppelin/ownership/Shareable.sol b/test/compilationTests/zeppelin/ownership/Shareable.sol
new file mode 100644
index 00000000..9fdaccfd
--- /dev/null
+++ b/test/compilationTests/zeppelin/ownership/Shareable.sol
@@ -0,0 +1,189 @@
+pragma solidity ^0.4.11;
+
+
+/**
+ * @title Shareable
+ * @dev inheritable "property" contract that enables methods to be protected by requiring the
+ * acquiescence of either a single, or, crucially, each of a number of, designated owners.
+ * @dev Usage: use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by some number (specified in constructor) of the set of owners (specified in the constructor) before the interior is executed.
+ */
+contract Shareable {
+
+ // struct for the status of a pending operation.
+ struct PendingState {
+ uint256 yetNeeded;
+ uint256 ownersDone;
+ uint256 index;
+ }
+
+ // the number of owners that must confirm the same operation before it is run.
+ uint256 public required;
+
+ // list of owners
+ address[256] owners;
+ // index on the list of owners to allow reverse lookup
+ mapping(address => uint256) ownerIndex;
+ // the ongoing operations.
+ mapping(bytes32 => PendingState) pendings;
+ bytes32[] pendingsIndex;
+
+
+ // this contract only has six types of events: it can accept a confirmation, in which case
+ // we record owner and operation (hash) alongside it.
+ event Confirmation(address owner, bytes32 operation);
+ event Revoke(address owner, bytes32 operation);
+
+
+ // simple single-sig function modifier.
+ modifier onlyOwner {
+ if (!isOwner(msg.sender)) {
+ throw;
+ }
+ _;
+ }
+
+ /**
+ * @dev Modifier for multisig functions.
+ * @param _operation The operation must have an intrinsic hash in order that later attempts can be
+ * realised as the same underlying operation and thus count as confirmations.
+ */
+ modifier onlymanyowners(bytes32 _operation) {
+ if (confirmAndCheck(_operation)) {
+ _;
+ }
+ }
+
+ /**
+ * @dev Constructor is given the number of sigs required to do protected "onlymanyowners"
+ * transactions as well as the selection of addresses capable of confirming them.
+ * @param _owners A list of owners.
+ * @param _required The amount required for a transaction to be approved.
+ */
+ function Shareable(address[] _owners, uint256 _required) {
+ owners[1] = msg.sender;
+ ownerIndex[msg.sender] = 1;
+ for (uint256 i = 0; i < _owners.length; ++i) {
+ owners[2 + i] = _owners[i];
+ ownerIndex[_owners[i]] = 2 + i;
+ }
+ required = _required;
+ if (required > owners.length) {
+ throw;
+ }
+ }
+
+ /**
+ * @dev Revokes a prior confirmation of the given operation.
+ * @param _operation A string identifying the operation.
+ */
+ function revoke(bytes32 _operation) external {
+ uint256 index = ownerIndex[msg.sender];
+ // make sure they're an owner
+ if (index == 0) {
+ return;
+ }
+ uint256 ownerIndexBit = 2**index;
+ var pending = pendings[_operation];
+ if (pending.ownersDone & ownerIndexBit > 0) {
+ pending.yetNeeded++;
+ pending.ownersDone -= ownerIndexBit;
+ Revoke(msg.sender, _operation);
+ }
+ }
+
+ /**
+ * @dev Gets an owner by 0-indexed position (using numOwners as the count)
+ * @param ownerIndex uint256 The index of the owner
+ * @return The address of the owner
+ */
+ function getOwner(uint256 ownerIndex) external constant returns (address) {
+ return address(owners[ownerIndex + 1]);
+ }
+
+ /**
+ * @dev Checks if given address is an owner.
+ * @param _addr address The address which you want to check.
+ * @return True if the address is an owner and fase otherwise.
+ */
+ function isOwner(address _addr) constant returns (bool) {
+ return ownerIndex[_addr] > 0;
+ }
+
+ /**
+ * @dev Function to check is specific owner has already confirme the operation.
+ * @param _operation The operation identifier.
+ * @param _owner The owner address.
+ * @return True if the owner has confirmed and false otherwise.
+ */
+ function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
+ var pending = pendings[_operation];
+ uint256 index = ownerIndex[_owner];
+
+ // make sure they're an owner
+ if (index == 0) {
+ return false;
+ }
+
+ // determine the bit to set for this owner.
+ uint256 ownerIndexBit = 2**index;
+ return !(pending.ownersDone & ownerIndexBit == 0);
+ }
+
+ /**
+ * @dev Confirm and operation and checks if it's already executable.
+ * @param _operation The operation identifier.
+ * @return Returns true when operation can be executed.
+ */
+ function confirmAndCheck(bytes32 _operation) internal returns (bool) {
+ // determine what index the present sender is:
+ uint256 index = ownerIndex[msg.sender];
+ // make sure they're an owner
+ if (index == 0) {
+ throw;
+ }
+
+ var pending = pendings[_operation];
+ // if we're not yet working on this operation, switch over and reset the confirmation status.
+ if (pending.yetNeeded == 0) {
+ // reset count of confirmations needed.
+ pending.yetNeeded = required;
+ // reset which owners have confirmed (none) - set our bitmap to 0.
+ pending.ownersDone = 0;
+ pending.index = pendingsIndex.length++;
+ pendingsIndex[pending.index] = _operation;
+ }
+ // determine the bit to set for this owner.
+ uint256 ownerIndexBit = 2**index;
+ // make sure we (the message sender) haven't confirmed this operation previously.
+ if (pending.ownersDone & ownerIndexBit == 0) {
+ Confirmation(msg.sender, _operation);
+ // ok - check if count is enough to go ahead.
+ if (pending.yetNeeded <= 1) {
+ // enough confirmations: reset and run interior.
+ delete pendingsIndex[pendings[_operation].index];
+ delete pendings[_operation];
+ return true;
+ } else {
+ // not enough: record that this owner in particular confirmed.
+ pending.yetNeeded--;
+ pending.ownersDone |= ownerIndexBit;
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * @dev Clear the pending list.
+ */
+ function clearPending() internal {
+ uint256 length = pendingsIndex.length;
+ for (uint256 i = 0; i < length; ++i) {
+ if (pendingsIndex[i] != 0) {
+ delete pendings[pendingsIndex[i]];
+ }
+ }
+ delete pendingsIndex;
+ }
+
+}