giveth-bridge
Version:
Mainnet -> sidechain Giveth Bridge.
72 lines • 78.7 kB
JSON
{
"language": "Solidity",
"sources": {
"./contracts/GivethBridgeMock.sol": {
"keccak256": "0x1a5a2094e0b3170615ca2f7af3cd6b80e293a5f605b51bcb053ccfe164d65343",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/GivethBridgeMock.sol"
],
"content": "pragma solidity ^0.4.21;\n/*\n Copyright 2017, RJ Ewing\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n*/\n\nimport \"./GivethBridge.sol\";\n\n/// @dev `GivethBridgeMock` allows for mocking up\n/// a `GivethBridge` contract with the added ability\n/// to manipulate the block time for testing purposes.\ncontract GivethBridgeMock is GivethBridge {\n\n uint public mock_time;\n\n function GivethBridgeMock(\n address _escapeHatchCaller,\n address _escapeHatchDestination,\n uint _absoluteMinTimeLock,\n uint _timeLock,\n address _securityGuard,\n uint _maxSecurityGuardDelay\n ) GivethBridge(\n _escapeHatchCaller,\n _escapeHatchDestination,\n _absoluteMinTimeLock,\n _timeLock,\n _securityGuard,\n _maxSecurityGuardDelay\n ) public\n {\n }\n\n /// @dev `_getTime` is a basic getter function for\n /// the mock_time parameter\n function _getTime() internal view returns (uint) {\n return mock_time;\n }\n\n /// @dev `setMockedTime` is a basic setter function for\n /// the mock_time parameter\n /// @param _t This is the value to which the mocked time\n /// will be set.\n function setMockedTime(uint _t) public {\n mock_time = _t;\n }\n}"
},
"giveth-common-contracts/contracts/ERC20.sol": {
"keccak256": "0xe58902b5bdf9f918c6ec8ee4da44bf87faf225098fae84671ab07b46af427338",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/node_modules/giveth-common-contracts/contracts/ERC20.sol"
],
"content": "pragma solidity ^0.4.19;\n\n\n/**\n * @title ERC20\n * @dev A standard interface for tokens.\n * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md\n */\ncontract ERC20 {\n \n /// @dev Returns the total token supply\n function totalSupply() public constant returns (uint256 supply);\n\n /// @dev Returns the account balance of the account with address _owner\n function balanceOf(address _owner) public constant returns (uint256 balance);\n\n /// @dev Transfers _value number of tokens to address _to\n function transfer(address _to, uint256 _value) public returns (bool success);\n\n /// @dev Transfers _value number of tokens from address _from to address _to\n function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);\n\n /// @dev Allows _spender to withdraw from the msg.sender's account up to the _value amount\n function approve(address _spender, uint256 _value) public returns (bool success);\n\n /// @dev Returns the amount which _spender is still allowed to withdraw from _owner\n function allowance(address _owner, address _spender) public constant returns (uint256 remaining);\n\n event Transfer(address indexed _from, address indexed _to, uint256 _value);\n event Approval(address indexed _owner, address indexed _spender, uint256 _value);\n\n}\n"
},
"giveth-common-contracts/contracts/Owned.sol": {
"keccak256": "0xc7d1401775fb1b41187de281757de68718fe27ba2660ba4bb194436aab7d0213",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/node_modules/giveth-common-contracts/contracts/Owned.sol"
],
"content": "pragma solidity ^0.4.19;\n\n\n/// @title Owned\n/// @author Adrià Massanet <adria@codecontext.io>\n/// @notice The Owned contract has an owner address, and provides basic \n/// authorization control functions, this simplifies & the implementation of\n/// user permissions; this contract has three work flows for a change in\n/// ownership, the first requires the new owner to validate that they have the\n/// ability to accept ownership, the second allows the ownership to be\n/// directly transfered without requiring acceptance, and the third allows for\n/// the ownership to be removed to allow for decentralization \ncontract Owned {\n\n address public owner;\n address public newOwnerCandidate;\n\n event OwnershipRequested(address indexed by, address indexed to);\n event OwnershipTransferred(address indexed from, address indexed to);\n event OwnershipRemoved();\n\n /// @dev The constructor sets the `msg.sender` as the`owner` of the contract\n function Owned() public {\n owner = msg.sender;\n }\n\n /// @dev `owner` is the only address that can call a function with this\n /// modifier\n modifier onlyOwner() {\n require (msg.sender == owner);\n _;\n }\n \n /// @dev In this 1st option for ownership transfer `proposeOwnership()` must\n /// be called first by the current `owner` then `acceptOwnership()` must be\n /// called by the `newOwnerCandidate`\n /// @notice `onlyOwner` Proposes to transfer control of the contract to a\n /// new owner\n /// @param _newOwnerCandidate The address being proposed as the new owner\n function proposeOwnership(address _newOwnerCandidate) public onlyOwner {\n newOwnerCandidate = _newOwnerCandidate;\n OwnershipRequested(msg.sender, newOwnerCandidate);\n }\n\n /// @notice Can only be called by the `newOwnerCandidate`, accepts the\n /// transfer of ownership\n function acceptOwnership() public {\n require(msg.sender == newOwnerCandidate);\n\n address oldOwner = owner;\n owner = newOwnerCandidate;\n newOwnerCandidate = 0x0;\n\n OwnershipTransferred(oldOwner, owner);\n }\n\n /// @dev In this 2nd option for ownership transfer `changeOwnership()` can\n /// be called and it will immediately assign ownership to the `newOwner`\n /// @notice `owner` can step down and assign some other address to this role\n /// @param _newOwner The address of the new owner\n function changeOwnership(address _newOwner) public onlyOwner {\n require(_newOwner != 0x0);\n\n address oldOwner = owner;\n owner = _newOwner;\n newOwnerCandidate = 0x0;\n\n OwnershipTransferred(oldOwner, owner);\n }\n\n /// @dev In this 3rd option for ownership transfer `removeOwnership()` can\n /// be called and it will immediately assign ownership to the 0x0 address;\n /// it requires a 0xdece be input as a parameter to prevent accidental use\n /// @notice Decentralizes the contract, this operation cannot be undone \n /// @param _dac `0xdac` has to be entered for this function to work\n function removeOwnership(address _dac) public onlyOwner {\n require(_dac == 0xdac);\n owner = 0x0;\n newOwnerCandidate = 0x0;\n OwnershipRemoved(); \n }\n} \n"
},
"giveth-common-contracts/contracts/Escapable.sol": {
"keccak256": "0xd5d7b1a916841b21cfdee2bc9de4a178820421252b0c764070d78e846cd4511d",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/node_modules/giveth-common-contracts/contracts/Escapable.sol"
],
"content": "pragma solidity ^0.4.19;\n/*\n Copyright 2016, Jordi Baylina\n Contributor: Adrià Massanet <adria@codecontext.io>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n*/\n\nimport \"./Owned.sol\";\nimport \"./ERC20.sol\";\n\n\n/// @dev `Escapable` is a base level contract built off of the `Owned`\n/// contract; it creates an escape hatch function that can be called in an\n/// emergency that will allow designated addresses to send any ether or tokens\n/// held in the contract to an `escapeHatchDestination` as long as they were\n/// not blacklisted\ncontract Escapable is Owned {\n address public escapeHatchCaller;\n address public escapeHatchDestination;\n mapping (address=>bool) private escapeBlacklist; // Token contract addresses\n\n /// @notice The Constructor assigns the `escapeHatchDestination` and the\n /// `escapeHatchCaller`\n /// @param _escapeHatchCaller The address of a trusted account or contract\n /// to call `escapeHatch()` to send the ether in this contract to the\n /// `escapeHatchDestination` it would be ideal that `escapeHatchCaller`\n /// cannot move funds out of `escapeHatchDestination`\n /// @param _escapeHatchDestination The address of a safe location (usu a\n /// Multisig) to send the ether held in this contract; if a neutral address\n /// is required, the WHG Multisig is an option:\n /// 0x8Ff920020c8AD673661c8117f2855C384758C572 \n function Escapable(address _escapeHatchCaller, address _escapeHatchDestination) public {\n escapeHatchCaller = _escapeHatchCaller;\n escapeHatchDestination = _escapeHatchDestination;\n }\n\n /// @dev The addresses preassigned as `escapeHatchCaller` or `owner`\n /// are the only addresses that can call a function with this modifier\n modifier onlyEscapeHatchCallerOrOwner {\n require ((msg.sender == escapeHatchCaller)||(msg.sender == owner));\n _;\n }\n\n /// @notice Creates the blacklist of tokens that are not able to be taken\n /// out of the contract; can only be done at the deployment, and the logic\n /// to add to the blacklist will be in the constructor of a child contract\n /// @param _token the token contract address that is to be blacklisted \n function blacklistEscapeToken(address _token) internal {\n escapeBlacklist[_token] = true;\n EscapeHatchBlackistedToken(_token);\n }\n\n /// @notice Checks to see if `_token` is in the blacklist of tokens\n /// @param _token the token address being queried\n /// @return False if `_token` is in the blacklist and can't be taken out of\n /// the contract via the `escapeHatch()`\n function isTokenEscapable(address _token) view public returns (bool) {\n return !escapeBlacklist[_token];\n }\n\n /// @notice The `escapeHatch()` should only be called as a last resort if a\n /// security issue is uncovered or something unexpected happened\n /// @param _token to transfer, use 0x0 for ether\n function escapeHatch(address _token) public onlyEscapeHatchCallerOrOwner { \n require(escapeBlacklist[_token]==false);\n\n uint256 balance;\n\n /// @dev Logic for ether\n if (_token == 0x0) {\n balance = this.balance;\n escapeHatchDestination.transfer(balance);\n EscapeHatchCalled(_token, balance);\n return;\n }\n /// @dev Logic for tokens\n ERC20 token = ERC20(_token);\n balance = token.balanceOf(this);\n require(token.transfer(escapeHatchDestination, balance));\n EscapeHatchCalled(_token, balance);\n }\n\n /// @notice Changes the address assigned to call `escapeHatch()`\n /// @param _newEscapeHatchCaller The address of a trusted account or\n /// contract to call `escapeHatch()` to send the value in this contract to\n /// the `escapeHatchDestination`; it would be ideal that `escapeHatchCaller`\n /// cannot move funds out of `escapeHatchDestination`\n function changeHatchEscapeCaller(address _newEscapeHatchCaller) public onlyEscapeHatchCallerOrOwner {\n escapeHatchCaller = _newEscapeHatchCaller;\n }\n\n event EscapeHatchBlackistedToken(address token);\n event EscapeHatchCalled(address token, uint amount);\n}\n"
},
"./contracts/lib/Pausable.sol": {
"keccak256": "0xd134809350f024c16096d995915c6a348d770e1ec633723419f4f3acbd1e4b46",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/lib/Pausable.sol"
],
"content": "pragma solidity ^0.4.21;\n\nimport \"giveth-common-contracts/contracts/Owned.sol\";\n\n/**\n * @title Pausable\n * @dev Base contract which allows children to implement an emergency stop mechanism.\n */\ncontract Pausable is Owned {\n event Pause();\n event Unpause();\n\n bool public paused = false;\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n */\n modifier whenNotPaused() {\n require(!paused);\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n */\n modifier whenPaused() {\n require(paused);\n _;\n }\n\n /**\n * @dev called by the owner to pause, triggers stopped state\n */\n function pause() onlyOwner whenNotPaused public {\n paused = true;\n emit Pause();\n }\n\n /**\n * @dev called by the owner to unpause, returns to normal state\n */\n function unpause() onlyOwner whenPaused public {\n paused = false;\n emit Unpause();\n }\n}"
},
"./contracts/lib/Vault.sol": {
"keccak256": "0x519df8e782548ae72e234de6f5c294def03beb3a3f9308093908311ba0bcd64a",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/lib/Vault.sol"
],
"content": "pragma solidity ^0.4.21;\n\n/*\n Copyright 2018, Jordi Baylina, RJ Ewing\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/// @title Vault Contract\n/// @author Jordi Baylina, RJ Ewing\n/// @notice This contract holds funds for Campaigns and automates payments. For\n/// this iteration the funds will come straight from the Giveth Multisig as a\n/// safety precaution, but once fully tested and optimized this contract will\n/// be a safe place to store funds equipped with optional variable time delays\n/// to allow for an optional escape hatch\n\nimport \"giveth-common-contracts/contracts/Escapable.sol\";\nimport \"./Pausable.sol\";\n\n/// @dev `Vault` is a higher level contract built off of the `Escapable`\n/// contract that holds funds for Campaigns and automates payments.\ncontract Vault is Escapable, Pausable {\n\n /// @dev `Payment` is a public structure that describes the details of\n /// each payment making it easy to track the movement of funds\n /// transparently\n struct Payment {\n string name; // What is the purpose of this payment\n bytes32 reference; // Reference of the payment.\n address spender; // Who is sending the funds\n uint earliestPayTime; // The earliest a payment can be made (Unix Time)\n bool canceled; // If True then the payment has been canceled\n bool paid; // If True then the payment has been paid\n address recipient; // Who is receiving the funds\n address token; // Token this payment represents\n uint amount; // The amount of wei sent in the payment\n uint securityGuardDelay; // The seconds `securityGuard` can delay payment\n }\n\n Payment[] public authorizedPayments;\n\n address public securityGuard;\n uint public absoluteMinTimeLock;\n uint public timeLock;\n uint public maxSecurityGuardDelay;\n bool public allowDisbursePaymentWhenPaused;\n\n /// @dev The white list of approved addresses allowed to set up && receive\n /// payments from this vault\n mapping (address => bool) public allowedSpenders;\n\n // @dev Events to make the payment movements easy to find on the blockchain\n event PaymentAuthorized(uint indexed idPayment, address indexed recipient, uint amount, address token, bytes32 reference);\n event PaymentExecuted(uint indexed idPayment, address indexed recipient, uint amount, address token);\n event PaymentCanceled(uint indexed idPayment);\n event SpenderAuthorization(address indexed spender, bool authorized);\n\n /// @dev The address assigned the role of `securityGuard` is the only\n /// addresses that can call a function with this modifier\n modifier onlySecurityGuard { \n require(msg.sender == securityGuard);\n _;\n }\n\n /// By default, we dis-allow payment disburements if the contract is paused.\n /// However, to facilitate a migration of the bridge, we can allow\n /// disbursements when paused if explicitly set\n modifier disbursementsAllowed {\n require(!paused || allowDisbursePaymentWhenPaused);\n _;\n }\n\n /// @notice The Constructor creates the Vault on the blockchain\n /// @param _escapeHatchCaller The address of a trusted account or contract to\n /// call `escapeHatch()` to send the ether in this contract to the\n /// `escapeHatchDestination` it would be ideal if `escapeHatchCaller` cannot move\n /// funds out of `escapeHatchDestination`\n /// @param _escapeHatchDestination The address of a safe location (usu a\n /// Multisig) to send the ether held in this contract in an emergency\n /// @param _absoluteMinTimeLock The minimum number of seconds `timelock` can\n /// be set to, if set to 0 the `owner` can remove the `timeLock` completely\n /// @param _timeLock Initial number of seconds that payments are delayed\n /// after they are authorized (a security precaution)\n /// @param _securityGuard Address that will be able to delay the payments\n /// beyond the initial timelock requirements; can be set to 0x0 to remove\n /// the `securityGuard` functionality\n /// @param _maxSecurityGuardDelay The maximum number of seconds in total\n /// that `securityGuard` can delay a payment so that the owner can cancel\n /// the payment if needed\n function Vault(\n address _escapeHatchCaller,\n address _escapeHatchDestination,\n uint _absoluteMinTimeLock,\n uint _timeLock,\n address _securityGuard,\n uint _maxSecurityGuardDelay\n ) Escapable(_escapeHatchCaller, _escapeHatchDestination) public\n {\n absoluteMinTimeLock = _absoluteMinTimeLock;\n timeLock = _timeLock;\n securityGuard = _securityGuard;\n maxSecurityGuardDelay = _maxSecurityGuardDelay;\n }\n\n/////////\n// Helper functions\n/////////\n\n /// @notice States the total number of authorized payments in this contract\n /// @return The number of payments ever authorized even if they were canceled\n function numberOfAuthorizedPayments() public view returns (uint) {\n return authorizedPayments.length;\n }\n\n////////\n// Spender Interface\n////////\n\n /// @notice only `allowedSpenders[]` Creates a new `Payment`\n /// @param _name Brief description of the payment that is authorized\n /// @param _reference External reference of the payment\n /// @param _recipient Destination of the payment\n /// @param _amount Amount to be paid in wei\n /// @param _paymentDelay Number of seconds the payment is to be delayed, if\n /// this value is below `timeLock` then the `timeLock` determines the delay\n /// @return The Payment ID number for the new authorized payment\n function authorizePayment(\n string _name,\n bytes32 _reference,\n address _recipient,\n address _token,\n uint _amount,\n uint _paymentDelay\n ) whenNotPaused external returns(uint) {\n\n // Fail if you arent on the `allowedSpenders` white list\n require(allowedSpenders[msg.sender]);\n uint idPayment = authorizedPayments.length; // Unique Payment ID\n authorizedPayments.length++;\n\n // The following lines fill out the payment struct\n Payment storage p = authorizedPayments[idPayment];\n p.spender = msg.sender;\n\n // Overflow protection\n require(_paymentDelay <= 10**18);\n\n // Determines the earliest the recipient can receive payment (Unix time)\n p.earliestPayTime = _paymentDelay >= timeLock ?\n _getTime() + _paymentDelay :\n _getTime() + timeLock;\n p.recipient = _recipient;\n p.amount = _amount;\n p.name = _name;\n p.reference = _reference;\n p.token = _token;\n emit PaymentAuthorized(idPayment, p.recipient, p.amount, p.token, p.reference);\n return idPayment;\n }\n\n /// Anyone can call this function to disburse the payment to \n /// the recipient after `earliestPayTime` has passed\n /// @param _idPayment The payment ID to be executed\n function disburseAuthorizedPayment(uint _idPayment) disbursementsAllowed public {\n // Check that the `_idPayment` has been added to the payments struct\n require(_idPayment < authorizedPayments.length);\n\n Payment storage p = authorizedPayments[_idPayment];\n\n // Checking for reasons not to execute the payment\n require(allowedSpenders[p.spender]);\n require(_getTime() >= p.earliestPayTime);\n require(!p.canceled);\n require(!p.paid);\n\n p.paid = true; // Set the payment to being paid\n\n // Make the payment\n if (p.token == 0) {\n p.recipient.transfer(p.amount);\n } else {\n require(ERC20(p.token).transfer(p.recipient, p.amount));\n }\n\n emit PaymentExecuted(_idPayment, p.recipient, p.amount, p.token);\n }\n\n /// convience function to disburse multiple payments in a single tx\n function disburseAuthorizedPayments(uint[] _idPayments) public {\n for (uint i = 0; i < _idPayments.length; i++) {\n uint _idPayment = _idPayments[i];\n disburseAuthorizedPayment(_idPayment);\n }\n }\n\n/////////\n// SecurityGuard Interface\n/////////\n\n /// @notice `onlySecurityGuard` Delays a payment for a set number of seconds\n /// @param _idPayment ID of the payment to be delayed\n /// @param _delay The number of seconds to delay the payment\n function delayPayment(uint _idPayment, uint _delay) onlySecurityGuard external {\n require(_idPayment < authorizedPayments.length);\n\n // Overflow test\n require(_delay <= 10**18);\n\n Payment storage p = authorizedPayments[_idPayment];\n\n require(p.securityGuardDelay + _delay <= maxSecurityGuardDelay);\n require(!p.paid);\n require(!p.canceled);\n\n p.securityGuardDelay += _delay;\n p.earliestPayTime += _delay;\n }\n\n////////\n// Owner Interface\n///////\n\n /// @notice `onlyOwner` Cancel a payment all together\n /// @param _idPayment ID of the payment to be canceled.\n function cancelPayment(uint _idPayment) onlyOwner external {\n require(_idPayment < authorizedPayments.length);\n\n Payment storage p = authorizedPayments[_idPayment];\n\n require(!p.canceled);\n require(!p.paid);\n\n p.canceled = true;\n emit PaymentCanceled(_idPayment);\n }\n\n /// @notice `onlyOwner` Adds a spender to the `allowedSpenders[]` white list\n /// @param _spender The address of the contract being authorized/unauthorized\n /// @param _authorize `true` if authorizing and `false` if unauthorizing\n function authorizeSpender(address _spender, bool _authorize) onlyOwner external {\n allowedSpenders[_spender] = _authorize;\n emit SpenderAuthorization(_spender, _authorize);\n }\n\n /// @notice `onlyOwner` Sets the address of `securityGuard`\n /// @param _newSecurityGuard Address of the new security guard\n function setSecurityGuard(address _newSecurityGuard) onlyOwner external {\n securityGuard = _newSecurityGuard;\n }\n\n /// @notice `onlyOwner` Changes `timeLock`; the new `timeLock` cannot be\n /// lower than `absoluteMinTimeLock`\n /// @param _newTimeLock Sets the new minimum default `timeLock` in seconds;\n /// pending payments maintain their `earliestPayTime`\n function setTimelock(uint _newTimeLock) onlyOwner external {\n require(_newTimeLock >= absoluteMinTimeLock);\n timeLock = _newTimeLock;\n }\n\n /// @notice `onlyOwner` Changes the maximum number of seconds\n /// `securityGuard` can delay a payment\n /// @param _maxSecurityGuardDelay The new maximum delay in seconds that\n /// `securityGuard` can delay the payment's execution in total\n function setMaxSecurityGuardDelay(uint _maxSecurityGuardDelay) onlyOwner external {\n maxSecurityGuardDelay = _maxSecurityGuardDelay;\n }\n\n /// @dev called by the owner to pause the contract. Triggers a stopped state \n /// and resets allowDisbursePaymentWhenPaused to false\n function pause() onlyOwner whenNotPaused public {\n allowDisbursePaymentWhenPaused = false;\n super.pause();\n }\n\n /// Owner can allow payment disbursement when the contract is paused. This is so the\n /// bridge can be upgraded without having to migrate any existing authorizedPayments\n /// @dev only callable whenPaused b/c pausing the contract will reset `allowDisbursePaymentWhenPaused` to false\n /// @param allowed `true` if allowing payments to be disbursed when paused, otherwise 'false'\n function setAllowDisbursePaymentWhenPaused(bool allowed) onlyOwner whenPaused public {\n allowDisbursePaymentWhenPaused = allowed;\n }\n\n // for overidding during testing\n function _getTime() internal view returns (uint) {\n return now;\n }\n\n}"
},
"./contracts/lib/FailClosedVault.sol": {
"keccak256": "0x62fc5761fc90bd42b4c504be4cb94f05343bd678452f5ed1e794b1e98a5174d1",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/lib/FailClosedVault.sol"
],
"content": "pragma solidity ^0.4.21;\n\n/*\n Copyright 2018, RJ Ewing\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport \"./Vault.sol\";\n\n/**\n* @dev `FailClosedVault` is a version of the vault that requires\n* the securityGuard to \"see\" each payment before it can be collected\n*/\ncontract FailClosedVault is Vault {\n uint public securityGuardLastCheckin;\n\n /**\n * @param _absoluteMinTimeLock For this version of the vault, it is recommended\n * that this value is > 24hrs. If not, it will require the securityGuard to checkIn\n * multiple times a day. Also consider that `securityGuardLastCheckin >= payment.earliestPayTime - timelock + 30mins);`\n * is the condition to allow payments to be payed. The additional 30 mins is to reduce (not eliminate)\n * the risk of front-running\n */\n function FailClosedVault(\n address _escapeHatchCaller,\n address _escapeHatchDestination,\n uint _absoluteMinTimeLock,\n uint _timeLock,\n address _securityGuard,\n uint _maxSecurityGuardDelay\n ) Vault(\n _escapeHatchCaller,\n _escapeHatchDestination, \n _absoluteMinTimeLock,\n _timeLock,\n _securityGuard,\n _maxSecurityGuardDelay\n ) public {\n }\n\n/////////////////////\n// Spender Interface\n/////////////////////\n\n /**\n * Disburse an authorizedPayment to the recipient if all checks pass.\n *\n * @param _idPayment The payment ID to be disbursed\n */\n function disburseAuthorizedPayment(uint _idPayment) disbursementsAllowed public {\n // Check that the `_idPayment` has been added to the payments struct\n require(_idPayment < authorizedPayments.length);\n\n Payment storage p = authorizedPayments[_idPayment];\n // The current minimum delay for a payment is `timeLock`. Thus the following ensuress\n // that the `securityGuard` has checked in after the payment was created\n // @notice earliestPayTime is updated when a payment is delayed. Which may require\n // another checkIn before the payment can be collected.\n // @notice We add 30 mins to this to reduce (not eliminate) the risk of front-running\n require(securityGuardLastCheckin >= p.earliestPayTime - timeLock + 30 minutes);\n\n super.disburseAuthorizedPayment(_idPayment);\n }\n\n///////////////////////////\n// SecurityGuard Interface\n///////////////////////////\n\n /**\n * @notice `onlySecurityGuard` can checkin. If they fail to checkin,\n * payments will not be allowed to be disbursed, unless the payment has\n * an `earliestPayTime` <= `securityGuardLastCheckin`.\n * @notice To reduce the risk of a front-running attack on payments, it\n * is important that this is called with a resonable gasPrice set for the\n * current network congestion. If this tx is not mined, within 30 mins\n * of being sent, it is possible that a payment can be authorized w/o the\n * securityGuard's knowledge\n */\n function checkIn() onlySecurityGuard external {\n securityGuardLastCheckin = _getTime();\n }\n}"
},
"./contracts/GivethBridge.sol": {
"keccak256": "0xd061316db9fd3c2ca1beeea0d5194d1c6fcc1b52de3c7fba4c8e449218203847",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/GivethBridge.sol"
],
"content": "pragma solidity ^0.4.21;\n\n/*\n Copyright 2017, RJ Ewing <perissology@protonmail.com>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n*/\n\nimport \"giveth-common-contracts/contracts/ERC20.sol\";\nimport \"./lib/FailClosedVault.sol\";\n\n\n/**\n* @notice It is not recommened to call this function outside of the giveth dapp (giveth.io)\n* this function is bridged to a side chain. If for some reason the sidechain tx fails, the donation\n* will end up in the givers control inside LiquidPledging contract. If you do not use the dapp, there\n* will be no way of notifying the sender/giver that the giver has to take action (withdraw/donate) in\n* the dapp\n*/\ncontract GivethBridge is FailClosedVault {\n\n mapping(address => bool) tokenWhitelist;\n\n event Donate(uint64 giverId, uint64 receiverId, address token, uint amount);\n event DonateAndCreateGiver(address giver, uint64 receiverId, address token, uint amount);\n event EscapeFundsCalled(address token, uint amount);\n\n //== constructor\n\n /**\n * @param _escapeHatchCaller The address of a trusted account or contract to\n * call `escapeHatch()` to send the ether in this contract to the\n * `escapeHatchDestination` in the case on an emergency. it would be ideal \n * if `escapeHatchCaller` cannot move funds out of `escapeHatchDestination`\n * @param _escapeHatchDestination The address of a safe location (usually a\n * Multisig) to send the ether held in this contract in the case of an emergency\n * @param _absoluteMinTimeLock The minimum number of seconds `timelock` can\n * be set to, if set to 0 the `owner` can remove the `timeLock` completely\n * @param _timeLock Minimum number of seconds that payments are delayed\n * after they are authorized (a security precaution)\n * @param _securityGuard Address that will be able to delay the payments\n * beyond the initial timelock requirements; can be set to 0x0 to remove\n * the `securityGuard` functionality\n * @param _maxSecurityGuardDelay The maximum number of seconds in total\n * that `securityGuard` can delay a payment so that the owner can cancel\n * the payment if needed\n */\n function GivethBridge(\n address _escapeHatchCaller,\n address _escapeHatchDestination,\n uint _absoluteMinTimeLock,\n uint _timeLock,\n address _securityGuard,\n uint _maxSecurityGuardDelay\n ) FailClosedVault(\n _escapeHatchCaller,\n _escapeHatchDestination,\n _absoluteMinTimeLock,\n _timeLock,\n _securityGuard,\n _maxSecurityGuardDelay\n ) public\n {\n tokenWhitelist[0] = true; // enable eth transfers\n }\n\n //== public methods\n\n /**\n * @notice It is not recommened to call this function outside of the giveth dapp (giveth.io)\n * this function is bridged to a side chain. If for some reason the sidechain tx fails, the donation\n * will end up in the givers control inside LiquidPledging contract. If you do not use the dapp, there\n * will be no way of notifying the sender/giver that the giver has to take action (withdraw/donate) in\n * the dapp\n *\n * @param giver The address to create a 'giver' pledge admin for in the liquidPledging contract\n * @param receiverId The adminId of the liquidPledging pledge admin receiving the donation\n */\n function donateAndCreateGiver(address giver, uint64 receiverId) payable external {\n donateAndCreateGiver(giver, receiverId, 0, 0);\n }\n\n /**\n * @notice It is not recommened to call this function outside of the giveth dapp (giveth.io)\n * this function is bridged to a side chain. If for some reason the sidechain tx fails, the donation\n * will end up in the givers control inside LiquidPledging contract. If you do not use the dapp, there\n * will be no way of notifying the sender/giver that the giver has to take action (withdraw/donate) in\n * the dapp\n *\n * @param giver The address to create a 'giver' pledge admin for in the liquidPledging contract\n * @param receiverId The adminId of the liquidPledging pledge admin receiving the donation\n * @param token The token to donate. If donating ETH, then 0x0. Note: the token must be whitelisted\n * @param _amount The amount of the token to donate. If donating ETH, then 0x0 as the msg.value will be used instead.\n */\n function donateAndCreateGiver(address giver, uint64 receiverId, address token, uint _amount) whenNotPaused payable public {\n require(giver != 0);\n require(receiverId != 0);\n uint amount = _receiveDonation(token, _amount);\n emit DonateAndCreateGiver(giver, receiverId, token, amount);\n }\n\n /**\n * @notice It is not recommened to call this function outside of the giveth dapp (giveth.io)\n * this function is bridged to a side chain. If for some reason the sidechain tx fails, the donation\n * will end up in the givers control inside LiquidPledging contract. If you do not use the dapp, there\n * will be no way of notifying the sender/giver that the giver has to take action (withdraw/donate) in\n * the dapp\n *\n * @param giverId The adminId of the liquidPledging pledge admin who is donating\n * @param receiverId The adminId of the liquidPledging pledge admin receiving the donation\n */\n function donate(uint64 giverId, uint64 receiverId) payable external {\n donate(giverId, receiverId, 0, 0);\n }\n\n /**\n * @notice It is not recommened to call this function outside of the giveth dapp (giveth.io)\n * this function is bridged to a side chain. If for some reason the sidechain tx fails, the donation\n * will end up in the givers control inside LiquidPledging contract. If you do not use the dapp, there\n * will be no way of notifying the sender/giver that the giver has to take action (withdraw/donate) in\n * the dapp\n *\n * @param giverId The adminId of the liquidPledging pledge admin who is donating\n * @param receiverId The adminId of the liquidPledging pledge admin receiving the donation\n * @param token The token to donate. If donating ETH, then 0x0. Note: the token must be whitelisted\n * @param _amount The amount of the token to donate. If donating ETH, then 0x0 as the msg.value will be used instead.\n */\n function donate(uint64 giverId, uint64 receiverId, address token, uint _amount) whenNotPaused payable public {\n require(giverId != 0);\n require(receiverId != 0);\n uint amount = _receiveDonation(token, _amount);\n emit Donate(giverId, receiverId, token, amount);\n }\n\n /**\n * The `owner` can call this function to add/remove a token from the whitelist\n *\n * @param token The address of the token to update\n * @param accepted Wether or not to accept this token for donations\n */\n function whitelistToken(address token, bool accepted) whenNotPaused onlyOwner external {\n tokenWhitelist[token] = accepted;\n }\n\n /**\n * Transfer tokens/eth to the escapeHatchDestination.\n * Used as a safety mechanism to prevent the bridge from holding too much value\n *\n * before being thoroughly battle-tested.\n * @param _token the token to transfer. 0x0 for ETH\n * @param _amount the amount to transfer\n */\n function escapeFunds(address _token, uint _amount) external onlyEscapeHatchCallerOrOwner {\n // @dev Logic for ether\n if (_token == 0) {\n escapeHatchDestination.transfer(_amount);\n // @dev Logic for tokens\n } else {\n ERC20 token = ERC20(_token);\n require(token.transfer(escapeHatchDestination, _amount));\n }\n emit EscapeFundsCalled(_token, _amount);\n }\n\n /**\n * Allow the escapeHatchDestination to deposit eth into this contract w/o calling donate method\n */\n function depositEscapedFunds() external payable {\n require(msg.sender == escapeHatchDestination);\n }\n\n //== internal methods\n\n /**\n * @dev used to actually receive the donation. Will transfer the token to to this contract\n */\n function _receiveDonation(address token, uint _amount) internal returns(uint amount) {\n require(tokenWhitelist[token]);\n amount = _amount;\n\n // eth donation\n if (token == 0) {\n amount = msg.value;\n }\n\n require(amount > 0);\n\n if (token != 0) {\n require(ERC20(token).transferFrom(msg.sender, this, amount));\n }\n }\n}"
},
"./contracts/IForeignGivethBridge.sol": {
"keccak256": "0x25fee627960da0977555015aba94373e56da5ddcc07d0d66724f0427344617af",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/IForeignGivethBridge.sol"
],
"content": "pragma solidity ^0.4.0;\n\n/*\n Copyright 2018, RJ Ewing <perissology@protonmail.com>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n*/\n\ninterface IForeignGivethBridge {\n event Deposit(address indexed sender, address token, uint amount, bytes32 homeTx, bytes data);\n event Withdraw(address indexed recipient, address token, uint amount);\n event TokenAdded(address indexed mainToken, address sideToken);\n\n function withdraw(address sideToken, uint amount) external;\n function withdraw(address recipient, address sideToken, uint amount) public;\n\n function deposit(address sender, address mainToken, uint amount, bytes32 homeTx, bytes data) external;\n function addToken(address mainToken, string tokenName, uint8 decimals, string tokenSymbol) external;\n}"
},
"./contracts/ForeignGivethBridge.sol": {
"keccak256": "0x9b874c40108c3d1892b77492d7665f0f764a647ddc5d1e4f9147c79c4c8ec6fd",
"urls": [
"file:///Users/rjewing/code/giveth/giveth-bridge/contracts/ForeignGivethBridge.sol"
],
"content": "pragma solidity ^0.4.21;\n\n/*\n Copyright 2018, RJ Ewing <perissology@protonmail.com>\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.\n*/\n\nimport \"giveth-common-contracts/contracts/Escapable.sol\";\nimport \"minimetoken/contracts/MiniMeToken.sol\";\nimport \"./lib/Pausable.sol\";\nimport \"./IForeignGivethBridge.sol\";\n\n\ncontract ForeignGivethBridge is IForeignGivethBridge, Escapable, Pausable, TokenController {\n MiniMeTokenFactory public tokenFactory;\n address public liquidPledging;\n address public depositor;\n\n mapping(address => address) public tokenMapping;\n mapping(address => address) public inverseTokenMapping;\n\n event Deposit(address indexed sender, address token, uint amount, bytes32 homeTx, bytes data);\n event Withdraw(address indexed recipient, address token, uint amount);\n event TokenAdded(address indexed mainToken, address sideToken);\n\n modifier onlyDepositor {\n require(msg.sender == depositor);\n _;\n }\n\n /**\n * @param _escapeHatchCaller The address of a trusted account or contract to\n * call `escapeHatch()` to send the ether in this contract to the\n * `escapeHatchDestination` in the case on an emergency. it would be ideal \n * if `escapeHatchCaller` cannot move funds out of `escapeHatchDestination`\n * @param _escapeHatchDestination The address of a safe location (usually a\n * Multisig) to send the ether held in this contract in the case of an emergency\n * @param _tokenFactory Address of the MiniMeTokenFactory instance used to deploy a new sideToken\n * @param _liquidPledging Address of the liquidPledging instance for this bridge\n * @param _depositor address that can deposit into this contract\n * @param mainTokens (optional) used for transferring existing tokens to a new bridge deployment.\n * There must be 1 mainToken for every sideToken\n * @param sideTokens (optional) used for transferring existing tokens to a new bridge deployment.\n * There must be 1 sideToken for every mainToken. Each sidetoken must inherit Controlled.sol \n * This contract will need to be set as the controller before the bridge can be used.\n */\n function ForeignGivethBridge(\n address _escapeHatchCaller,\n address _escapeHatchDestination, \n address _tokenFactory,\n address _liquidPledging,\n address _depositor,\n address[] mainTokens,\n address[] sideTokens\n ) Escapable(_escapeHatchCaller, _escapeHatchDestination) public \n {\n require(_tokenFactory != 0);\n require(_liquidPledging != 0);\n require(mainTokens.length == sideTokens.length);\n\n tokenFactory = MiniMeTokenFactory(_tokenFactory);\n liquidPledging = _liquidPledging;\n depositor = _depositor;\n\n for (uint i = 0; i < mainTokens.length; i++) {\n address mainToken = mainTokens[i];\n address sideToken = sideTokens[i];\n MiniMeToken(sideToken).approve(liquidPledging, uint(-1));\n tokenMapping[mainToken] = sideToken;\n inverseTokenMapping[sideToken] = mainToken;\n emit TokenAdded(mainToken, sideToken);\n }\n }\n\n////////////////////\n// Public Functions \n////////////////////\n\n /**\n * withdraw funds to the home network\n *\n * @dev This signals to the bridge service that we should release\n * tokens/eth on the home netowork to msg.sender\n * @param sideToken The token on this network we are withdrawing\n * @param amount The amount to withdraw\n */\n function withdraw(address sideToken, uint amount) external {\n withdraw(msg.sender, sideToken, amount);\n }\n\n /**\n * withdraw funds to the home network\n *\n * @dev This signals to the bridge service that we should release\n * tokens/eth on the home netowork to msg.sender\n * @param recipient The address we should release the funds to on the\n * home network\n * @param sideToken The token on this network we are withdrawing\n * @param amount The amount to withdraw\n */\n function withdraw(address recipient, address sideToken, uint amount) whenNotPaused public {\n address mainToken = inverseTokenMapping[sideToken];\n require(mainToken != 0 || tokenMapping[0] == sideToken);\n\n // burn the tokens we want to withdraw\n MiniMeToken(sideToken).destroyTokens(msg.sender, amount);\n\n emit Withdraw(recipient, mainToken, amount);\n }\n\n///////////////////////\n// Depositor Interface\n///////////////////////\n\n /**\n * deposit funds from the home network to this network\n *\n * @param sender The address on the home network that deposited the funds\n * @param mainToken The token on the main network we are depositing\n * @param amount The amount to withdraw\n * @param homeTx The hash of the tx on the home network where the funds were deposited\n * @param data The abi encoded data we call `liquidPledging` with. This should be some form\n * of \"donate\" on liquidPledging (donate, donateAndCreateGiver, etc);\n */\n function deposit(address sender, address mainToken, uint amount, bytes32 homeTx, bytes data) onlyDepositor external {\n address sideToken = tokenMapping[mainToken];\n // if the mainToken isn't mapped, we can't accept the deposit\n require(sideToken != 0);\n\n // mint tokens we are depositing\n MiniMeToken(sideToken).generateTokens(address(this), amount);\n\n // ensure that liquidPledging still as a transfer allownce from this contract\n // and topup if needed\n if (MiniMeToken(sideToken).allowance(address(this), liquidPledging) < amount) {\n // need to set to 0 before we can update\n MiniMeToken(sideToken).approve(liquidPledging, 0);\n MiniMeToken(sideToken).approve(liquidPledging, uint(-1));\n }\n\n require(liquidPledging.call(data));\n emit Deposit(sender, mainToken, amount, homeTx, data);\n }\n\n///////////////////\n// Owner Interface\n///////////////////\n\n /**\n * Map a token from the home network to this network. This will deploy\n * a new MiniMeToken \n *\n * @param mainToken The token on the home network we are mapping\n * @param tokenName The name of the MiniMeToken to be deployed\n * @param decimals The number of decimals the sideToken will have.\n * This should be the same as the mainToken\n * @param tokenSymbol The symbol of the MiniMeToken to be deployed\n */\n function addToken(address mainToken, string tokenName, uint8 decimals, string tokenSymbol) onlyOwner external {\n // ensure we haven't already mapped this token