Skip to content

Instantly share code, notes, and snippets.

@anubhavgirdhar
Created August 5, 2020 16:57
Show Gist options
  • Save anubhavgirdhar/c91511d924c2d0b55237c9bb98ffdb95 to your computer and use it in GitHub Desktop.
Save anubhavgirdhar/c91511d924c2d0b55237c9bb98ffdb95 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&gist=
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "./EIP712.sol";
import "./ERC20.sol";
import "./dsProxy.sol";
contract DsaForwarder is DSAuth, EIP712 {
bytes32 executeSig = bytes32(bytes4(keccak256("execute(address,bytes)")));
struct Signature {
bytes32 r;
bytes32 s;
uint8 v;
}
mapping(address => mapping(address => mapping(bytes4 => bool))) acl;
function canCall(
address src,
address dst,
bytes4 sig
) external view returns (bool) {
bytes32 _sig = bytes32(sig);
return src == address(this) && executeSig == _sig ? true : false;
}
function forward(
address signer,
Signature calldata signature,
address to,
bytes calldata data,
uint256 value,
address inputToken,
address outputToken
) external {
// Authentication check
DSAuth auth = DSAuth(to);
require(auth.owner() == signer, "Auth Failed");
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
signer,
nonces[signer]
)
)
)
);
require(signer != address(0), "invalid-address-0");
require(
signer == ecrecover(digest, signature.v, signature.r, signature.s),
"invalid-signatures"
);
_call(signer, to, data, inputToken, value, outputToken);
nonces[signer]++;
}
function _call(
address signer,
address to,
bytes memory data,
address _inputToken,
uint256 _value,
address _outputToken
) internal {
ERC20 erc20 = ERC20(_inputToken);
erc20.transferFrom(signer, address(this), _value);
erc20.approve(to, _value);
(bool success, ) = to.call(data);
if (!success) {
assembly {
let returnDataSize := returndatasize()
returndatacopy(0, 0, returnDataSize)
revert(0, returnDataSize)
}
} else {
ERC20 outputToken = ERC20(_outputToken);
outputToken.transfer(signer, outputToken.balanceOf(address(this)));
}
}
}
// call args
// "0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f","0x185b0Eec4Fd74DA335702207f77999181d0eFb1c","0x1cff79cd00000000000000000000000002efdb542b9390ae7c1620b29674e02f9c0d86cc00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000084c1762b1500000000000000000000000031670617b85451e5e3813e50442eed3ce3b68d19000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c00000000000000000000000000000000000000000000000001aa535d3d0c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","0xd0A1E359811322d97991E03f863a0C30C2cF029C","120000000000000000","0x31670617b85451e5e3813e50442eed3ce3b68d19"
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.4.0/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.4.0/contracts/token/ERC20/SafeERC20.sol";
contract Bunch {
using SafeERC20 for IERC20;
address ethAddress = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
function multiToken(address _target,address payable _address,uint _value) internal {
if(_target == ethAddress){
address(_address).transfer(_value);
}else{
IERC20 erc20 = IERC20(_target);
erc20.safeTransfer(_address,_value);
}
}
function execute(
address[] calldata tokenAddresses,
address payable[] calldata addresses,
uint[] calldata values
)
external
payable
{
for (uint i = 0; i < tokenAddresses.length; i++) {
multiToken(tokenAddresses[i], addresses[i],values[i]);
}
}
}
// guard.sol -- simple whitelist implementation of DSAuthority
// Copyright (C) 2017 DappHub, LLC
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.4.13;
contract DSAuthority {
function canCall(
address src, address dst, bytes4 sig
) public view returns (bool);
}
contract DSAuthEvents {
event LogSetAuthority (address indexed authority);
event LogSetOwner (address indexed owner);
}
contract DSAuth is DSAuthEvents {
DSAuthority public authority;
address public owner;
function DSAuth() public {
owner = msg.sender;
LogSetOwner(msg.sender);
}
function setOwner(address owner_)
public
auth
{
owner = owner_;
LogSetOwner(owner);
}
function setAuthority(DSAuthority authority_)
public
auth
{
authority = authority_;
LogSetAuthority(authority);
}
modifier auth {
require(isAuthorized(msg.sender, msg.sig));
_;
}
function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
if (src == address(this)) {
return true;
} else if (src == owner) {
return true;
} else if (authority == DSAuthority(0)) {
return false;
} else {
return authority.canCall(src, this, sig);
}
}
}
contract DSGuardEvents {
event LogPermit(
bytes32 indexed src,
bytes32 indexed dst,
bytes32 indexed sig
);
event LogForbid(
bytes32 indexed src,
bytes32 indexed dst,
bytes32 indexed sig
);
}
contract DSGuard is DSAuth, DSAuthority, DSGuardEvents {
bytes32 constant public ANY = bytes32(uint(-1));
mapping (bytes32 => mapping (bytes32 => mapping (bytes32 => bool))) acl;
function canCall(
address src_, address dst_, bytes4 sig
) public view returns (bool) {
var src = bytes32(src_);
var dst = bytes32(dst_);
return acl[src][dst][sig]
|| acl[src][dst][ANY]
|| acl[src][ANY][sig]
|| acl[src][ANY][ANY]
|| acl[ANY][dst][sig]
|| acl[ANY][dst][ANY]
|| acl[ANY][ANY][sig]
|| acl[ANY][ANY][ANY];
}
function permit(bytes32 src, bytes32 dst, bytes32 sig) public auth {
acl[src][dst][sig] = true;
LogPermit(src, dst, sig);
}
function forbid(bytes32 src, bytes32 dst, bytes32 sig) public auth {
acl[src][dst][sig] = false;
LogForbid(src, dst, sig);
}
function permit(address src, address dst, bytes32 sig) public {
permit(bytes32(src), bytes32(dst), sig);
}
function forbid(address src, address dst, bytes32 sig) public {
forbid(bytes32(src), bytes32(dst), sig);
}
}
contract DSGuardFactory {
mapping (address => bool) public isGuard;
function newGuard() public returns (DSGuard guard) {
guard = new DSGuard();
guard.setOwner(msg.sender);
isGuard[guard] = true;
}
}
// proxy.sol - execute actions atomically through the proxy's identity
// Copyright (C) 2017 DappHub, LLC
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity 0.5.12;
interface DSAuthority {
function canCall(
address src, address dst, bytes4 sig
) external view returns (bool);
}
contract DSAuthEvents {
event LogSetAuthority (address indexed authority);
event LogSetOwner (address indexed owner);
}
contract DSAuth is DSAuthEvents {
DSAuthority public authority;
address public owner;
constructor() public {
owner = msg.sender;
emit LogSetOwner(msg.sender);
}
function setOwner(address owner_)
public
auth
{
owner = owner_;
emit LogSetOwner(owner);
}
function setAuthority(DSAuthority authority_)
public
auth
{
authority = authority_;
emit LogSetAuthority(address(authority));
}
modifier auth {
require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized");
_;
}
function isAuthorized(address src, bytes4 sig) internal view returns (bool) {
if (src == address(this)) {
return true;
} else if (src == owner) {
return true;
} else if (authority == DSAuthority(0)) {
return false;
} else {
return authority.canCall(src, address(this), sig);
}
}
}
contract DSNote {
event LogNote(
bytes4 indexed sig,
address indexed guy,
bytes32 indexed foo,
bytes32 indexed bar,
uint256 wad,
bytes fax
) anonymous;
modifier note {
bytes32 foo;
bytes32 bar;
uint256 wad;
assembly {
foo := calldataload(4)
bar := calldataload(36)
wad := callvalue()
}
_;
emit LogNote(msg.sig, msg.sender, foo, bar, wad, msg.data);
}
}
// DSProxy
// Allows code execution using a persistant identity This can be very
// useful to execute a sequence of atomic actions. Since the owner of
// the proxy can be changed, this allows for dynamic ownership models
// i.e. a multisig
contract DSProxy is DSAuth, DSNote {
DSProxyCache public cache; // global cache for contracts
constructor(address _cacheAddr) public {
setCache(_cacheAddr);
}
function() external payable {
}
// use the proxy to execute calldata _data on contract _code
function execute(bytes memory _code, bytes memory _data)
public
payable
returns (address target, bytes memory response)
{
target = cache.read(_code);
if (target == address(0)) {
// deploy contract & store its address in cache
target = cache.write(_code);
}
response = execute(target, _data);
}
function execute(address _target, bytes memory _data)
public
auth
note
payable
returns (bytes memory response)
{
require(_target != address(0), "ds-proxy-target-address-required");
// call contract in current context
assembly {
let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
let size := returndatasize
response := mload(0x40)
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
revert(add(response, 0x20), size)
}
}
}
//set new cache
function setCache(address _cacheAddr)
public
auth
note
returns (bool)
{
require(_cacheAddr != address(0), "ds-proxy-cache-address-required");
cache = DSProxyCache(_cacheAddr); // overwrite cache
return true;
}
}
// DSProxyFactory
// This factory deploys new proxy instances through build()
// Deployed proxy addresses are logged
contract DSProxyFactory {
event Created(address indexed sender, address indexed owner, address proxy, address cache);
mapping(address=>bool) public isProxy;
DSProxyCache public cache;
constructor() public {
cache = new DSProxyCache();
}
// deploys a new proxy instance
// sets owner of proxy to caller
function build() public returns (address payable proxy) {
proxy = build(msg.sender);
}
// deploys a new proxy instance
// sets custom owner of proxy
function build(address owner) public returns (address payable proxy) {
proxy = address(new DSProxy(address(cache)));
emit Created(msg.sender, owner, address(proxy), address(cache));
DSProxy(proxy).setOwner(owner);
isProxy[proxy] = true;
}
}
// DSProxyCache
// This global cache stores addresses of contracts previously deployed
// by a proxy. This saves gas from repeat deployment of the same
// contracts and eliminates blockchain bloat.
// By default, all proxies deployed from the same factory store
// contracts in the same cache. The cache a proxy instance uses can be
// changed. The cache uses the sha3 hash of a contract's bytecode to
// lookup the address
contract DSProxyCache {
mapping(bytes32 => address) cache;
function read(bytes memory _code) public view returns (address) {
bytes32 hash = keccak256(_code);
return cache[hash];
}
function write(bytes memory _code) public returns (address target) {
assembly {
target := create(0, add(_code, 0x20), mload(_code))
switch iszero(extcodesize(target))
case 1 {
// throw if contract failed to deploy
revert(0, 0)
}
}
bytes32 hash = keccak256(_code);
cache[hash] = target;
}
}
pragma solidity ^0.5.0;
contract EIP712 {
mapping(address => uint256) public nonces;
struct EIP712Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}
struct MetaTransaction {
address holder;
uint256 nonce;
}
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"));
bytes32 internal constant META_TRANSACTION_TYPEHASH = keccak256(bytes("MetaTransaction(address holder,uint256 nonce)"));
bytes32 internal DOMAIN_SEPARATOR = keccak256(abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes("balancer")),
keccak256(bytes("1")),
42, // Kovan
address(this)
));
}
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "https://github.com/ensdomains/ens/blob/master/contracts/ENSRegistryWithFallback.sol";
pragma solidity ^0.5.0;
interface ERC20 {
function totalSupply() external view returns (uint supply);
function balanceOf(address _owner) external view returns (uint balance);
function transfer(address _to, uint _value) external returns (bool success);
function transferFrom(address _from, address _to, uint _value) external returns (bool success);
function approve(address _spender, uint _value) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint remaining);
function decimals() external view returns(uint digits);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
pragma solidity 0.5.0;
contract HashMyFunction{
function hashMe(address[] memory employeeToken,address payable[] memory employeeAddr,uint[] memory values) public pure returns(bytes memory){
return abi.encodeWithSignature("massPayout(address,address[],address[],uint256[])",0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, employeeToken,employeeAddr,values);
}
function test() external pure returns (bytes memory){
return abi.encodeWithSelector(bytes4(keccak256('setAuthority(address)')));
}
function ens() external pure returns (bytes32){
return bytes32(keccak256('delilah'));
}
function ens1() external pure returns (bytes32){
return bytes32(keccak256('ears'));
}
function ens2() external pure returns (bytes32){
return bytes32(keccak256('fork'));
}
function ens3() external pure returns (bytes32){
return bytes32(keccak256('gear'));
}
function ens4() external pure returns (bytes32){
return bytes32(keccak256('hen'));
}
}
pragma solidity ^0.6.0;
interface IENS {
function setOwner(bytes32 node, address owner) external;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
}
pragma solidity ^0.6.0;
interface IENSResolver {
function setAddr(bytes32 node, address addr) external;
function name(bytes32 node) external view returns (string memory);
}
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
/**
* @title ERC-1620 Money Streaming Standard
* @author Sablier
* @dev See https://eips.ethereum.org/EIPS/eip-1620
*/
interface IERC1620 {
/**
* @notice Emits when a stream is successfully created.
*/
event CreateStream(
uint256 indexed streamId,
address indexed sender,
address indexed recipient,
uint256 deposit,
address tokenAddress,
uint256 startTime,
uint256 stopTime
);
/**
* @notice Emits when the recipient of a stream withdraws a portion or all their pro rata share of the stream.
*/
event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);
/**
* @notice Emits when a stream is successfully cancelled and tokens are transferred back on a pro rata basis.
*/
event CancelStream(
uint256 indexed streamId,
address indexed sender,
address indexed recipient,
uint256 senderBalance,
uint256 recipientBalance
);
function balanceOf(uint256 streamId, address who) external view returns (uint256 balance);
function getStream(uint256 streamId)
external
view
returns (
address sender,
address recipient,
uint256 deposit,
address token,
uint256 startTime,
uint256 stopTime,
uint256 remainingBalance,
uint256 ratePerSecond
);
function createSalary(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime)
external
returns (uint256 streamId);
function withdrawFromStream(uint256 streamId, uint256 funds) external returns (bool);
function cancelStream(uint256 streamId) external returns (bool);
}
pragma solidity ^0.6.0;
interface ERC20 {
function totalSupply() external view returns (uint supply);
function balanceOf(address _owner) external view returns (uint balance);
function transfer(address _to, uint _value) external returns (bool success);
function transferFrom(address _from, address _to, uint _value) external returns (bool success);
function approve(address _spender, uint _value) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint remaining);
function decimals() external view returns(uint digits);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
pragma solidity ^0.6.0;
interface IReverseRegistrar {
function setName(string memory name) external returns (bytes32);
}
pragma solidity ^0.6.0;
interface IUniswap {
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function getAmountsOut(uint256 amountIn, address[] calldata path)
external
view
returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
}
pragma solidity ^0.5.0;
import "./ParcelStorage.sol";
import "./ERC20.sol";
interface UniswapInterface{
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
}
contract MultiSender is ParcelStorage{
address public ethAddress = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public uniswapRouterAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
UniswapInterface uniswap = UniswapInterface(uniswapRouterAddress);
address public WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
// address public DAI_ADDRESS = 0xc7ad46e0b8a400bb3c915120d284aafba8fc4735;
// address public USDC_ADDRESS = 0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b;
function massPayout(address employerToken,address[] memory employeeToken,address payable[] memory employeeAddress,uint[] memory values) public payable {
for (uint i = 0; i < employeeAddress.length; i++) {
if(employerToken == employeeToken[i]){
_send(employeeToken[i],employeeAddress[i],values[i]);
}else {
if(employerToken == ethAddress){
address[] memory _path = new address[](2);
_path[0] = WETH_ADDRESS;
_path[1] = employeeToken[i];
uint[] memory returnedAmount = getAmount(_path,values[i]);
uniswap.swapExactETHForTokens.value(values[i])(returnedAmount[1],_path,employeeAddress[i], now + 12000);
// swapExactEthToTokens.value(values[i])(_path,values[i]);
}
if(employerToken != ethAddress && employeeToken[i] == ethAddress){
address[] memory _path = new address[](2);
_path[0] = employerToken;
_path[1] = WETH_ADDRESS;
swapExactTokensToEth(_path,values[i],employeeAddress[i]);
}
if(employerToken != ethAddress && employeeToken[i] != ethAddress){
address[] memory _path = new address[](3);
_path[0] = employerToken;
_path[1] = WETH_ADDRESS;
_path[2] = employeeToken[i];
swapTokenToToken(_path,values[i],employeeAddress[i]);
}
}
}
}
// "0xc7ad46e0b8a400bb3c915120d284aafba8fc4735",["0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b","0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"],["0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f","0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f"],["100000000000000000","100000000000000000"]
// "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE","0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"],["0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f","0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f"],["100000000000000000","100000000000000000"]
// Rinkeby Addresses
// DAI : ["0xc7ad46e0b8a400bb3c915120d284aafba8fc4735",
// WETH : "0xc778417e063141139fce010982780140aa0cd5ab"]
// USDC : 0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b
// IN path : to, WETH, from
function swapTokenToToken(address[] memory path, uint amountIn,address _employeeAddresss)internal {
uint[] memory returnedAmount = getAmount(path,amountIn);
ERC20 erc20 = ERC20(path[0]);
erc20.approve(uniswapRouterAddress,amountIn);
uniswap.swapExactTokensForTokens(returnedAmount[0],returnedAmount[2],path,_employeeAddresss, now + 12000);
}
function swapExactTokensToEth(address[] memory path, uint amountIn, address _employeeAddresss)internal {
uint[] memory returnedAmount = getAmount(path,amountIn);
ERC20 erc20 = ERC20(path[0]);
erc20.approve(uniswapRouterAddress,amountIn);
uniswap.swapExactTokensForETH(returnedAmount[0],returnedAmount[1],path,_employeeAddresss, now + 12000);
}
// function swapExactEthToTokens(address[] memory path, uint amountInEth) public payable {
// uint[] memory returnedAmount = getAmount(path,amountInEth);
// uniswap.swapExactETHForTokens.value(amountInEth)(returnedAmount[1],path,address(this), now + 12000);
// }
function getAmount(address[] memory path, uint amountInEth) internal view returns(uint[] memory){
uint[] memory returnedAmount = uniswap.getAmountsOut(amountInEth,path);
return returnedAmount;
}
function _send(address _employeeToken,address payable _employeeAddress,uint _value) internal {
if(_employeeToken == ethAddress){
(_employeeAddress).transfer(_value);
}else{
ERC20 erc20 = ERC20(_employeeToken);
erc20.transfer(_employeeAddress,_value);
}
}
function() external payable {
}
}
// 0x535b5e207Be78Ca93bf5B751b3B19afcFd4Dc9d7
//["0xd0A1E359811322d97991E03f863a0C30C2cF029C","0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa"],"100000000000000"
pragma solidity ^0.5.0;
import "parcelProxy.sol";
interface ENS {
// Logged when the owner of a node assigns a new owner to a subnode.
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.
event Transfer(bytes32 indexed node, address owner);
// Logged when the resolver for a node changes.
event NewResolver(bytes32 indexed node, address resolver);
// Logged when the TTL of a node changes
event NewTTL(bytes32 indexed node, uint64 ttl);
// Logged when an operator is added or removed.
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external;
function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external;
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external returns(bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
// function isApprovedForAll(address owner, address operator) external view returns (bool);
}
contract ParcelRegistry {
mapping(address => address) public registered;
address public publicResolverAddr = 0xf6305c19e814d2a75429Fd637d01F7ee0E77d615;
IENSResolver ENSResolver = IENSResolver(publicResolverAddr);
IENS ENSRegistry = IENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
// modifier oneAccount {
// require(registered[msg.sender] == address(0), "account exists");
// _;
// }
function changeENSOwner(bytes32 _node, address _newOwner) external {
ENSRegistry.setOwner(_node, _newOwner);
}
function register(
bytes32 _node,
bytes32 _label,
bytes32 _ownerNode
) external payable returns (address) {
ENSRegistry.setSubnodeRecord(
_node,
_label,
address(this),
publicResolverAddr,
0
);
ENSResolver.setAddr(_ownerNode, address(this));
ParcelWallet newAccount = new ParcelWallet(msg.sender);
registered[msg.sender] = address(newAccount);
ENSRegistry.setSubnodeOwner(_node, _label, address(newAccount));
IENSResolver myAccount = IENSResolver(address(newAccount));
myAccount.setAddr(_ownerNode, address(newAccount));
return address(newAccount);
}
}
// Public resolver : 0xf6305c19e814d2a75429fd637d01f7ee0e77d615
// parcelpay.eth namehash
// 0x80fcc19e84f9861048b415dfeb3aadd7737e20ab244c3fd19e572d92ecc65617
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "./parcelStorage.sol";
interface PublicResolver{
function setAddr(bytes32 node, address addr) external;
}
contract ParcelProxy is ParcelStorage {
address public publicResolverAddr = 0xf6305c19e814d2a75429Fd637d01F7ee0E77d615;
PublicResolver ENSResolver = PublicResolver(publicResolverAddr);
// constructor(address _owner) public {
// owner = _owner;
// }
function setAddr(bytes32 node, address addr) external{
ENSResolver.setAddr(node,addr);
}
modifier onlyOwner {
require(msg.sender == owner, "Not the Owner");
_;
}
/**
* @dev Delegate the calls to Connector And this function is ran by cast().
* @param _target Target to of Connector.
* @param _data CallData of function in Connector.
*/
function _call(address _target, bytes memory _data) internal {
require(_target != address(0), "target-invalid");
assembly {
let succeeded := delegatecall(
gas(),
_target,
add(_data, 0x20),
mload(_data),
0,
0
)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
let size := returndatasize()
returndatacopy(0x00, 0x00, size)
revert(0x00, size)
}
}
}
function convert() public view returns (bytes32){
return bytes32(keccak256('QmYo9HRSvrFkrQBj6xRYKRUPXLbpMsaCxXVsfX4kXfK1Rs'));
}
/**
* @dev This is the main function
* @param targets Array of Target(s) to of Implementation.
* @param data Array of Calldata(s) of function.
*/
function execute(address[] calldata targets, bytes[] calldata data)
external
payable
{
for (uint256 i = 0; i < targets.length; i++) {
_call(targets[i], data[i]);
}
}
function() external payable {}
function addFile(uint8 index, string calldata hash) external {
files[index] = hash;
}
}
pragma solidity ^0.5.0;
// import "./uniswapInterface.sol";
// import "./cTokenInterface.sol";
// import "./ERC20.sol";
// import "./comptrollerInterface.sol";
// import "./aaveInterface.sol";
// import "./aTokenInterface.sol";
interface ILendingPoolAddressesProvider {
function getLendingPool() external view returns (address);
}
contract ParcelStorage{
address public uniswapRouterAddress = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
// UniswapInterface uniswap = UniswapInterface(uniswapRouterAddress);
address WETH_KOVAN = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
address DAI_KOVAN = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
address cEthAddress = 0xf92FbE0D3C0dcDAE407923b2Ac17eC223b1084E4;
// cTokenInterface cEth = cTokenInterface(cEthAddress);
address cDaiAddress = 0xe7bc397DBd069fC7d0109C0636d06888bb50668c;
// cTokenInterface cDai = cTokenInterface(cDaiAddress);
address comptrollerAddress = 0x1f5D7F3CaAC149fE41b8bd62A3673FE6eC0AB73b;
// comptrollerInterface comptroller = comptrollerInterface(comptrollerAddress);
// cTokenInterface dai = cTokenInterface(DAI_KOVAN);
address public owner;
// // Retrieve LendingPool address
// ILendingPoolAddressesProvider provider = ILendingPoolAddressesProvider(address(0x506B0B2CF20FAA8f38a4E2B524EE43e1f4458Cc5)); // mainnet address, for other addresses: https://docs.aave.com/developers/developing-on-aave/deployed-contract-instances
// LendingPool lendingPool = LendingPool(provider.getLendingPool());
// Input variables
address ethAddress = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
uint16 referral = 0;
}
pragma solidity ^0.5.0;
contract ParcelStorage {
address public owner;
mapping(uint8 => string) public files;
}
pragma solidity ^0.6.0;
import "./parelWallet.sol";
import "./IENS.sol";
import "./IERC20.sol";
contract ParcelFactory {
mapping(address => address) public registered;
address public publicResolverAddr = 0xf6305c19e814d2a75429Fd637d01F7ee0E77d615;
IENSResolver ENSResolver = IENSResolver(publicResolverAddr);
IENS ENSRegistry = IENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
// modifier oneAccount {
// require(registered[msg.sender] == address(0), "account exists");
// _;
// }
function changeENSOwner(bytes32 _node, address _newOwner) external {
ENSRegistry.setOwner(_node, _newOwner);
}
function register(
bytes32 _node,
bytes32 _label,
bytes32 _ownerNode
) external payable returns (address) {
ENSRegistry.setSubnodeRecord(
_node,
_label,
address(this),
publicResolverAddr,
0
);
ENSResolver.setAddr(_ownerNode, address(this));
ParcelWallet newAccount = new ParcelWallet(msg.sender);
registered[msg.sender] = address(newAccount);
ENSRegistry.setSubnodeOwner(_node, _label, address(newAccount));
IENSResolver myAccount = IENSResolver(address(newAccount));
myAccount.setAddr(_ownerNode, address(newAccount));
// ERC20 erc20 = ERC20(0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735);
// erc20.transfer(address(newAccount),5000000000000000000);
return address(newAccount);
}
function resolver(bytes32 node) external view returns (string memory){
return ENSResolver.name(node);
}
}
// parcelid.eth ---- 0x15eac8f5a11394d34a5b1073c9555027ae0ad90090cfa79b91bf12b4a3413670
//delilah.parcelid.eth ---- 0xe70ec8a964956485d7e66c1cbaf6ad8240e27cd7149704e4e0ebd5c83fcd47e0
pragma solidity ^0.6.0;
import "./IENSResolver.sol";
import "./IReverseRegistrar.sol";
import "./IUniswap.sol";
import "./IERC1620.sol";
contract ParcelStorage {
address public owner;
mapping(uint8 => string) public files;
address public publicResolverAddr = 0xf6305c19e814d2a75429Fd637d01F7ee0E77d615;
IENSResolver ENSResolver = IENSResolver(publicResolverAddr);
address public reverseRegistrar = 0x6F628b68b30Dc3c17f345c9dbBb1E483c2b7aE5c;
IReverseRegistrar ReverseRegistrar = IReverseRegistrar(ReverseRegistrar);
address public ethAddress = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public uniswapRouterAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
IUniswap uniswap = IUniswap(uniswapRouterAddress);
address public WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
address public sablierAddress = 0x7ee114C3628Ca90119fC699f03665bF9dB8f5faF;
IERC1620 sablier = IERC1620(sablierAddress); // get a handle for the Sablier contract
}
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./parelStorage.sol";
import "./IERC20.sol";
contract ParcelWallet is ParcelStorage {
constructor(address _owner) public {
owner = _owner;
}
modifier onlyOwner {
require(msg.sender == owner, "Not the Owner");
_;
}
function addFile(uint8 index, string calldata hash) external onlyOwner {
files[index] = hash;
}
function setAddr(bytes32 node, address addr) external {
ENSResolver.setAddr(node, addr);
ReverseRegistrar.setName();
}
/**
* @dev Delegate the calls to Connector And this function is ran by cast().
* @param _target Target to of Connector.
* @param _data CallData of function in Connector.
*/
function _call(address _target, bytes memory _data) internal {
require(_target != address(0), "target-invalid");
assembly {
let succeeded := delegatecall(
gas(),
_target,
add(_data, 0x20),
mload(_data),
0,
0
)
switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
let size := returndatasize()
returndatacopy(0x00, 0x00, size)
revert(0x00, size)
}
}
}
/**
* @dev This is the main function
* @param targets Array of Target(s) to of Implementation.
* @param data Array of Calldata(s) of function.
*/
function execute(address[] calldata targets, bytes[] calldata data)
external
payable
onlyOwner
{
for (uint256 i = 0; i < targets.length; i++) {
_call(targets[i], data[i]);
}
}
// Rinkeby Addresses
// DAI : "0xc7ad46e0b8a400bb3c915120d284aafba8fc4735",
// WETH : "0xc778417e063141139fce010982780140aa0cd5ab"
// USDC : 0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b
function massPayout(
address employerToken,
address[] memory employeeToken,
address payable[] memory employeeAddress,
uint256[] memory values
) public payable {
for (uint256 i = 0; i < employeeAddress.length; i++) {
if (employerToken == employeeToken[i]) {
_send(employeeToken[i], employeeAddress[i], values[i]);
} else {
if (employerToken == ethAddress) {
address[] memory _path = new address[](2);
_path[0] = WETH_ADDRESS;
_path[1] = employeeToken[i];
uint256[] memory returnedAmount = getAmount(
_path,
values[i]
);
uniswap.swapExactETHForTokens{value:(values[i])}(
returnedAmount[1],
_path,
employeeAddress[i],
now + 12000
);
// swapExactEthToTokens.value(values[i])(_path,values[i]);
}
if (
employerToken != ethAddress &&
employeeToken[i] == ethAddress
) {
address[] memory _path = new address[](2);
_path[0] = employerToken;
_path[1] = WETH_ADDRESS;
swapExactTokensToEth(_path, values[i], employeeAddress[i]);
}
if (
employerToken != ethAddress &&
employeeToken[i] != ethAddress
) {
address[] memory _path = new address[](3);
_path[0] = employerToken;
_path[1] = WETH_ADDRESS;
_path[2] = employeeToken[i];
swapTokenToToken(_path, values[i], employeeAddress[i]);
}
}
}
}
// IN path : to, WETH, from
function swapTokenToToken(
address[] memory path,
uint256 amountOut,
address _employeeAddresss
) internal {
// uint256[] memory returnedAmount = getAmount(path, amountIn);
ERC20 erc20 = ERC20(path[0]);
erc20.approve(uniswapRouterAddress, uint(-1));
uniswap.swapTokensForExactTokens(
amountOut,
uint(-1),
path,
_employeeAddresss,
now + 12000
);
}
function swapExactTokensToEth(
address[] memory path,
uint256 amountIn,
address _employeeAddresss
) internal {
uint256[] memory returnedAmount = getAmount(path, amountIn);
ERC20 erc20 = ERC20(path[0]);
erc20.approve(uniswapRouterAddress, amountIn);
uniswap.swapExactTokensForETH(
returnedAmount[0],
returnedAmount[1],
path,
_employeeAddresss,
now + 12000
);
}
// function swapExactEthToTokens(address[] memory path, uint amountInEth) public payable {
// uint[] memory returnedAmount = getAmount(path,amountInEth);
// uniswap.swapExactETHForTokens.value(amountInEth)(returnedAmount[1],path,address(this), now + 12000);
// }
function getAmount(address[] memory path, uint256 amountInEth)
internal
view
returns (uint256[] memory)
{
uint256[] memory returnedAmount = uniswap.getAmountsOut(
amountInEth,
path
);
return returnedAmount;
}
function _send(
address _employeeToken,
address payable _employeeAddress,
uint256 _value
) internal {
if (_employeeToken == ethAddress) {
(_employeeAddress).transfer(_value);
} else {
ERC20 erc20 = ERC20(_employeeToken);
erc20.transfer(_employeeAddress, _value);
}
}
// "0xc7ad46e0b8a400bb3c915120d284aafba8fc4735",["0x4dbcdf9b62e891a7cec5a2568c3f4faf9e8abe2b","0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"],["0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f","0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f"],["100000000000000000","100000000000000000"]
// "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE","0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"],["0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f","0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f"],["100000000000000000","100000000000000000"]
// Money Streaming
function streamMoney(address[] calldata recipients,uint256[] calldata values, address[] calldata tokensToStream, uint256[] calldata stopTime)external returns (uint256[] memory) {
uint256[] memory ids = new uint256[](recipients.length);
for(uint i = 0; i < recipients.length; i++){
ERC20 token = ERC20(tokensToStream[i]); // get a handle for the token contract
token.approve(address(sablier),uint(-1));
// the stream id is needed later to withdraw from or cancel the stream
uint256 streamId = sablier.createSalary(recipients[i], values[i], tokensToStream[i], block.timestamp , block.timestamp + stopTime[i]);
ids[i] = streamId;
}
return ids;
}
//["0x277CC1637C6BaABBfD92656C09564D9B61d5B3BC","0x277CC1637C6BaABBfD92656C09564D9B61d5B3BC"],["999999999999997200","999999999999997200"],["0xc3dbf84Abb494ce5199D5d4D815b10EC29529ff8","0xc3dbf84Abb494ce5199D5d4D815b10EC29529ff8"],["3600","3600"]
function withdraw()external {
ERC20 erc20 = ERC20(0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735);
uint bal = erc20.balanceOf(address(this));
erc20.transfer(msg.sender,bal);
}
fallback() external payable {}
receive() external payable {}
}
// PARCEL WALLET ( Execute Function) =========> Mass Payout Contract ( Masspayout function)
massPayout(arg1,arg2,arg3);
let hashMassPayouts =
function massPayout(
address employerToken,
address[] memory employeeToken,
address payable[] memory employeeAddress,
uint256[] memory values
)
Parcel Wallet == Execute([0xbbbjhbbb],[hashMassPayouts])
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "./IERC20.sol";
import "./IERC1620.sol";
contract TrySablier {
address public sablierAddress = 0x7ee114C3628Ca90119fC699f03665bF9dB8f5faF;
IERC1620 sablier = IERC1620(sablierAddress); // get a handle for the Sablier contract
// address public daiSablierRinkeby = 0xc3dbf84Abb494ce5199D5d4D815b10EC29529ff8;
// address recipient = 0x36eC99A4CA6F1a3E3299aEB94587F34A9E6adA1f;
// uint256 deposit = 2999999999999998944000; // almost 3,000, but not quite
// uint256 startTime = block.timestamp + 180; // 1 hour from now
// uint256 stopTime = block.timestamp + 2592000 + 180 ; // 30 days and 1 hour from now
function streamMoney(address recipient, address tokenToStream)external returns (uint256) {
ERC20 token = ERC20(tokenToStream); // get a handle for the token contract
token.approve(address(sablier),uint(-1));
// the stream id is needed later to withdraw from or cancel the stream
uint256 deposit = 2999999999999998944000; // almost 3,000, but not quite
uint256 startTime = block.timestamp + 180; // 1 hour from now
uint256 stopTime = block.timestamp + 2592000 + 180 ; // 30 days and 1 hour from now
uint256 streamId = sablier.createSalary(recipient, deposit, address(token), startTime, stopTime);
return streamId;
}
}
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "./ParcelStorage.sol";
import "./ERC20.sol";
contract Bunch is ParcelStorage{
// @dev Delegate the calls to Connector And this function is ran by execute().
// * @param _target Target to of Connector.
// * @param _data CallData of function in Connector.
// */
// function _call(address _target, bytes memory _data) internal {
// require(_target != address(0), "target-invalid");
// assembly {
// let succeeded := delegatecall(
// gas(),
// _target,
// add(_data, 0x20),
// mload(_data),
// 0,
// 0
// )
// switch iszero(succeeded)
// case 1 {
// // throw if delegatecall failed
// let size := returndatasize()
// returndatacopy(0x00, 0x00, size)
// revert(0x00, size)
// }
// }
// }
function multiToken(address targets,address payable addresses,uint values) internal {
if(targets == ethAddress){
address(addresses).transfer(values);
}else{
ERC20 erc20 = ERC20(targets);
erc20.transfer(addresses,values);
}
}
function execute(
address[] calldata targets,
address payable[] calldata addresses,
uint[] calldata values
)
external
payable
{
for (uint i = 0; i < targets.length; i++) {
multiToken(targets[i], addresses[i],values[i]);
}
}
}
pragma solidity ^0.5.0;
import "parcelProxy.sol";
interface ENS {
// Logged when the owner of a node assigns a new owner to a subnode.
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.
event Transfer(bytes32 indexed node, address owner);
// Logged when the resolver for a node changes.
event NewResolver(bytes32 indexed node, address resolver);
// Logged when the TTL of a node changes
event NewTTL(bytes32 indexed node, uint64 ttl);
// Logged when an operator is added or removed.
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external;
function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external;
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external returns(bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
// function isApprovedForAll(address owner, address operator) external view returns (bool);
}
interface PublicResolver{
function setAddr(bytes32 node, address addr) external;
}
contract Test {
mapping(address => address) public registered;
ENS ENSRegistry = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
address public publicResolverAddr = 0xf6305c19e814d2a75429Fd637d01F7ee0E77d615;
PublicResolver ENSResolver = PublicResolver(publicResolverAddr);
// modifier oneAccount {
// require(registered[msg.sender] == address(0), "account exists");
// _;
// }
function changeENSOwner(bytes32 _node, address _newOwner)external {
ENSRegistry.setOwner(_node,_newOwner);
}
function createSubDomain(bytes32 _node, bytes32 _label, address _ownerOfSubdomain) external {
ENSRegistry.setSubnodeOwner(_node,_label,_ownerOfSubdomain);
}
function createSubnodeOwner(bytes32 _node, bytes32 _label, address _ownerOfSubdomain) external {
ENSRegistry.setSubnodeRecord(_node,_label,_ownerOfSubdomain,publicResolverAddr,0);
}
function change(bytes32 _node, bytes32 _label, address _ownerOfSubdomain) external {
ENSRegistry.setSubnodeOwner(_node,_label,_ownerOfSubdomain);
}
function create(bytes32 _node, bytes32 _label, address _ownerOfSubdomain) external {
ENSRegistry.setSubnodeRecord(_node,_label,address(this),publicResolverAddr,0);
}
function setAdd(bytes32 _ownerNode , address _owner) external {
ENSResolver.setAddr(_ownerNode,address(this));
}
function register() external payable returns (address) {
ParcelProxy newAccount = new ParcelProxy(msg.sender);
registered[msg.sender] = address(newAccount);
}
}
// Public resolver : 0xf6305c19e814d2a75429fd637d01f7ee0e77d615
// parcelpay.eth namehash
// 0x80fcc19e84f9861048b415dfeb3aadd7737e20ab244c3fd19e572d92ecc65617
pragma solidity ^0.5.0;
contract Tester {
address ethAddress = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
address public uniswapRouterAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
address public WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
function testMe()external view returns(address[] memory){
address[] memory _path = new address[](2);
_path[0] = WETH_ADDRESS;
_path[1] = ethAddress;
return _path;
}
}
pragma solidity ^0.6.0;
interface AddNumbers { function add(uint256 a, uint256 b) external returns (uint256 c); }
contract Example {
AddNumbers addContract;
event StringFailure(string stringFailure);
event BytesFailure(bytes bytesFailure);
function addNew(address _new)external {
addContract = AddNumbers(_new);
}
function exampleFunction(uint256 _a, uint256 _b) public returns (uint256 _c) {
try addContract.add(_a, _b) returns (uint256 _value) {
return (_value);
} catch Error(string memory _err) {
// This may occur if there is an overflow with the two numbers and the `AddNumbers` contract explicitly fails with a `revert()`
emit StringFailure(_err);
} catch (bytes memory _err) {
emit BytesFailure(_err);
}
}
}
pragma solidity ^0.6.0;
uint public x;
contract AddNumbers {
function add(uint256 a, uint256 b) external pure returns (uint256 c){
require(a > 10, "No shit");
return a+b;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment