Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/contracts/GasTester.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.2;

contract GasTester {

Expand Down
4 changes: 2 additions & 2 deletions contracts/contracts/TestToken.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.2;

import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol";

contract TestToken is ERC20 {
contract TestToken is ERC20UpgradeSafe {

function mint(address account, uint256 amount) public {
_mint(account, amount);
Expand Down
60 changes: 48 additions & 12 deletions contracts/contracts/Umbra.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
pragma solidity ^0.5.0;
pragma solidity ^0.6.2;

import "@openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";
import "@opengsn/gsn/contracts/BaseRelayRecipient.sol";
import "@opengsn/gsn/contracts/interfaces/IRelayHub.sol";

contract Umbra is Ownable, ReentrancyGuard {
contract Umbra is BaseRelayRecipient, OwnableUpgradeSafe {
using SafeMath for uint256;

struct TokenPayment {
address token;
uint256 amount;
}

event Announcement(
address indexed receiver,
uint256 indexed amount,
Expand All @@ -22,15 +28,26 @@ contract Umbra is Ownable, ReentrancyGuard {
bytes32 mac // Message Authetnication Code
);

event TokenWithdrawl(
address indexed receiver,
address indexed acceptor,
uint256 amount,
address indexed token
);

address constant ETH_TOKEN_PLACHOLDER = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

uint256 public toll;
address public tollCollector;
address payable public tollReceiver;
mapping (address => TokenPayment) tokenPayments;

constructor(uint256 _toll, address _tollCollector, address payable _tollReceiver) public {
initialize(msg.sender);
constructor(uint256 _toll, address _tollCollector, address payable _tollReceiver, address _gsnForwarder) public {
__Ownable_init();
toll = _toll;
tollCollector = _tollCollector;
tollReceiver = _tollReceiver;
trustedForwarder = _gsnForwarder;
}

function setToll(uint256 _newToll) public onlyOwner {
Expand All @@ -45,6 +62,10 @@ contract Umbra is Ownable, ReentrancyGuard {
tollReceiver = _newTollReceiver;
}

function setForwarder(address _forwarder) public onlyOwner {
trustedForwarder = _forwarder;
}

function sendEth(
address payable _receiver,
bytes16 _iv, // Inivitalization Vector
Expand All @@ -57,12 +78,11 @@ contract Umbra is Ownable, ReentrancyGuard {
)
public
payable
nonReentrant
{
require(msg.value > toll, "Umbra: Must pay more than the toll");

uint256 amount = msg.value.sub(toll);
emit Announcement(_receiver, amount, address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE), _iv, _pkx, _pky, _ct0, _ct1, _ct2, _mac);
emit Announcement(_receiver, amount, ETH_TOKEN_PLACHOLDER, _iv, _pkx, _pky, _ct0, _ct1, _ct2, _mac);

_receiver.transfer(amount);
}
Expand All @@ -81,21 +101,37 @@ contract Umbra is Ownable, ReentrancyGuard {
)
public
payable
nonReentrant
{
require(msg.value == toll, "Umbra: Must pay the exact toll");

tokenPayments[_receiver] = TokenPayment({token: _tokenAddr, amount: _amount});
emit Announcement(_receiver, _amount, _tokenAddr, _iv, _pkx, _pky, _ct0, _ct1, _ct2, _mac);

SafeERC20.safeTransferFrom(IERC20(_tokenAddr), msg.sender, _receiver, _amount);
SafeERC20.safeTransferFrom(IERC20(_tokenAddr), _msgSender(), address(this), _amount);
}

function withdrawToken(address _acceptor) public {
uint256 amount = tokenPayments[_msgSender()].amount;
address tokenAddr = tokenPayments[_msgSender()].token;

require(amount > 0, "Umbra: No tokens available for withdrawl");

delete tokenPayments[_msgSender()];
emit TokenWithdrawl(_msgSender(), _acceptor, amount, tokenAddr);

SafeERC20.safeTransfer(IERC20(tokenAddr), _acceptor, amount);
}

function _msgSender() internal override(ContextUpgradeSafe, BaseRelayRecipient) view returns (address payable) {
return BaseRelayRecipient._msgSender();
}

function collectTolls() public onlyCollector nonReentrant {
function collectTolls() public onlyCollector {
tollReceiver.transfer(address(this).balance);
}

modifier onlyCollector() {
require(msg.sender == tollCollector, "Umbra: Not Toll Collector");
require(_msgSender() == tollCollector, "Umbra: Not Toll Collector");
_;
}
}
41 changes: 41 additions & 0 deletions contracts/contracts/UmbraPaymaster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pragma solidity ^0.6.2;
pragma experimental ABIEncoderV2;

import "@opengsn/gsn/contracts/BasePaymaster.sol";

contract UmbraPaymaster is BasePaymaster {

address public umbraAddr;

constructor(address _umbraAddr) public {
umbraAddr = _umbraAddr;
}

function acceptRelayedCall(
GSNTypes.RelayRequest calldata relayRequest ,
bytes calldata approvalData,
uint256 maxPossibleGas
) external view override returns (bytes memory context) {
(approvalData, maxPossibleGas); // avoid a warning

require(relayRequest.target == umbraAddr, "UmbraPaymaster: Not Target");

return abi.encode(0x0);
}

function preRelayedCall(
bytes calldata context
) external relayHubOnly override returns(bytes32) {
return bytes32(0);
}

function postRelayedCall(
bytes calldata context,
bool success,
bytes32 preRetVal,
uint256 gasUse,
GSNTypes.GasData calldata gasData
) external relayHubOnly override {
(success, preRetVal, gasUse, gasData);
}
}
Loading