Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x2CD26a9AB2630C85D06C9a93338b35da173E4e30
Balance 0 ETH
Nonce 1
Code Size 9023 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9023 bytes
0x6080604052600436106101e35760003560e01c80639e9f695d11610102578063cd41ced011610095578063eba760d611610064578063eba760d614610691578063ed8f584b146106af578063f2fde38b146106d7578063f9fb452f146106f757600080fd5b8063cd41ced0146105b7578063dc3aaab5146105d7578063e086e5ec146105f5578063eb84e7f21461060a57600080fd5b8063a89ae4ba116100d1578063a89ae4ba14610535578063ad70127814610555578063bfe22a0114610581578063cce987d4146105a157600080fd5b80639e9f695d146104b5578063a06bbf08146104d5578063a1734e60146104f5578063a3e676101461051557600080fd5b80634c69c00f1161017a5780638a2e386e116101495780638a2e386e1461038e5780638d17359e146103a15780638da5cb5b146103b7578063933a59db146103d557600080fd5b80634c69c00f14610319578063565e6d1c14610339578063715018a6146103595780637c0bf7bb1461036e57600080fd5b806318e02bd9116101b657806318e02bd91461028f57806322f3e2d4146102af578063315a095d146102d95780634bc10ccb146102f957600080fd5b806306b091f9146101e85780631028e4921461020a57806310fe9ae81461023d578063113d4e1e1461026f575b600080fd5b3480156101f457600080fd5b50610208610203366004611fe1565b610718565b005b34801561021657600080fd5b5061022a610225366004612042565b6108e3565b6040519081526020015b60405180910390f35b34801561024957600080fd5b506001546001600160a01b03165b6040516001600160a01b039091168152602001610234565b34801561027b57600080fd5b5061020861028a366004611fc0565b610b82565b34801561029b57600080fd5b506102086102aa366004611fc0565b610bec565b3480156102bb57600080fd5b506009546102c99060ff1681565b6040519015158152602001610234565b3480156102e557600080fd5b506102086102f4366004612042565b610cbd565b34801561030557600080fd5b50610208610314366004611fc0565b610daf565b34801561032557600080fd5b50610208610334366004611fc0565b610dfb565b34801561034557600080fd5b50610208610354366004612072565b610e4f565b34801561036557600080fd5b50610208610ea3565b34801561037a57600080fd5b50610208610389366004611fc0565b610ed9565b61020861039c3660046120a1565b610f25565b3480156103ad57600080fd5b5061022a60085481565b3480156103c357600080fd5b506000546001600160a01b0316610257565b3480156103e157600080fd5b5061045c6103f0366004611fc0565b600b602052600090815260409020805460018201546002830154600384015460049094015492939192909160ff80821692610100830482169262010000810483169263010000008204811692640100000000830490911691600160281b90046001600160a01b0316908a565b604080519a8b5260208b01999099529789019690965293151560608801529115156080870152151560a0860152151560c0850152151560e08401526001600160a01b031661010083015261012082015261014001610234565b3480156104c157600080fd5b506102086104d03660046120cc565b611305565b3480156104e157600080fd5b506102086104f03660046120cc565b61134f565b34801561050157600080fd5b50610208610510366004612042565b61138f565b34801561052157600080fd5b50600454610257906001600160a01b031681565b34801561054157600080fd5b50600554610257906001600160a01b031681565b34801561056157600080fd5b5060075461056f9060ff1681565b60405160ff9091168152602001610234565b34801561058d57600080fd5b5061020861059c36600461200a565b6115e3565b3480156105ad57600080fd5b5061022a60065481565b3480156105c357600080fd5b506102086105d2366004612042565b61167a565b3480156105e357600080fd5b506002546001600160a01b0316610257565b34801561060157600080fd5b506102086116a9565b34801561061657600080fd5b5061045c610625366004612042565b600a602052600090815260409020805460018201546002830154600384015460049094015492939192909160ff80821692610100830482169262010000810483169263010000008204811692640100000000830490911691600160281b90046001600160a01b0316908a565b34801561069d57600080fd5b506003546001600160a01b0316610257565b6106c26106bd366004612042565b61172e565b60408051928352602083019190915201610234565b3480156106e357600080fd5b506102086106f2366004611fc0565b611d0c565b34801561070357600080fd5b5060025461056f90600160a01b900460ff1681565b6000546001600160a01b0316331461074b5760405162461bcd60e51b81526004016107429061213d565b60405180910390fd5b81816107cd576040516370a0823160e01b81523060048201526001600160a01b038216906370a082319060240160206040518083038186803b15801561079057600080fd5b505afa1580156107a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c8919061205a565b6107cf565b815b91506000821161083c5760405162461bcd60e51b815260206004820152603260248201527f6d616b65207375726520746865726520697320612062616c616e636520617661604482015271696c61626c6520746f20776974686472617760701b6064820152608401610742565b806001600160a01b031663a9059cbb61085d6000546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101859052604401602060405180830381600087803b1580156108a557600080fd5b505af11580156108b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108dd9190612026565b50505050565b60095460009060ff166109085760405162461bcd60e51b815260040161074290612172565b6000828152600a602090815260409182902082516101408101845281548152600182015492810192909252600281015492820192909252600382015460ff808216151560608401526101008083048216151560808501526201000083048216151560a0850152630100000083048216151560c08501526401000000008304909116151560e0840152600160281b9091046001600160a01b03169082015260048201546101208201526109b990611da4565b600481015460075460ff1615610a82576007546109da9060ff16600a61221c565b600360009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a2857600080fd5b505afa158015610a3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6091906120e8565b610a6b90600a61221c565b610a7590836122c9565b610a7f91906121b9565b90505b600380549083015460405163a9059cbb60e01b81526001600160a01b03600160281b909204821660048201526024810184905291169063a9059cbb90604401602060405180830381600087803b158015610adb57600080fd5b505af1158015610aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b139190612026565b5042600283015560038201805461010061ff0019909116179081905560408051600160281b9092046001600160a01b031682526020820183905285917f5426fb0d0815408493c5f4929e0ed09d2ed7e5bb76c81b768453c1257dae292d910160405180910390a2509192915050565b6000546001600160a01b03163314610bac5760405162461bcd60e51b81526004016107429061213d565b6001600160a01b03166000908152600b6020526040812081815560018101829055600281018290556003810180546001600160c81b031916905560040155565b6004546001600160a01b03163314610c5c5760405162461bcd60e51b815260206004820152602d60248201527f75736572206d7573742062652063757272656e7420746f6b656e206f776e657260448201526c081d1bc818da185b99d9481a5d609a1b6064820152608401610742565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f58c4666d1756c527d157a91550f4ca84593b1353eea2528168c1ff4be2113706910160405180910390a15050565b6004546001600160a01b03163314610d275760405162461bcd60e51b815260206004820152602760248201527f7769746864726177546f6b656e732075736572206d75737420626520746f6b65604482015266371037bbb732b960c91b6064820152608401610742565b60035460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015610d7357600080fd5b505af1158015610d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dab9190612026565b5050565b6000546001600160a01b03163314610dd95760405162461bcd60e51b81526004016107429061213d565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610e255760405162461bcd60e51b81526004016107429061213d565b600580546001600160a01b0319166001600160a01b038316908117909155610e4c90611d0c565b50565b6000546001600160a01b03163314610e795760405162461bcd60e51b81526004016107429061213d565b6000918252600a602052604090912060030180549115156101000261ff0019909216919091179055565b6000546001600160a01b03163314610ecd5760405162461bcd60e51b81526004016107429061213d565b610ed76000611ed4565b565b6000546001600160a01b03163314610f035760405162461bcd60e51b81526004016107429061213d565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600854341015610f965760405162461bcd60e51b815260206004820152603660248201527f796f75206d7573742073656e6420656e6f7567682067617320746f20636f766560448201527539103a34329039b2b732103a3930b739b0b1ba34b7b760511b6064820152608401610742565b6040516bffffffffffffffffffffffff193360601b166020820152603481018390526054810182905260029060740160408051601f1981840301815290829052610fdf91612104565b602060405180830381855afa158015610ffc573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061101f919061205a565b831461106d5760405162461bcd60e51b815260206004820152601d60248201527f776520646f206e6f74207265636f676e697a65207468697320737761700000006044820152606401610742565b6000838152600a6020526040902060030154640100000000900460ff16156110d05760405162461bcd60e51b815260206004820152601660248201527531b0b73737ba10333ab7321039bbb0b81030b3b0b4b760511b6044820152606401610742565b6008541561112f576005546008546040516001600160a01b0390921691600081818185875af1925050503d8060008114611126576040519150601f19603f3d011682016040523d82523d6000602084013e61112b565b606091505b5050505b604051806101400160405280848152602001838152602001428152602001600115158152602001600a600086815260200190815260200160002060030160019054906101000a900460ff1615158152602001600a600086815260200190815260200160002060030160029054906101000a900460ff1615158152602001600a600086815260200190815260200160002060030160039054906101000a900460ff1615158152602001600115158152602001336001600160a01b0316815260200182815250600a600085815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548160ff02191690831515021790555060a08201518160030160026101000a81548160ff02191690831515021790555060c08201518160030160036101000a81548160ff02191690831515021790555060e08201518160030160046101000a81548160ff0219169083151502179055506101008201518160030160056101000a8154816001600160a01b0302191690836001600160a01b031602179055506101208201518160040155905050505050565b6000546001600160a01b0316331461132f5760405162461bcd60e51b81526004016107429061213d565b6002805460ff909216600160a01b0260ff60a01b19909216919091179055565b6000546001600160a01b031633146113795760405162461bcd60e51b81526004016107429061213d565b6007805460ff191660ff92909216919091179055565b60095460ff166113b15760405162461bcd60e51b815260040161074290612172565b6000818152600a6020526040902060038101546301000000900460ff16611442576040805162461bcd60e51b81526020600482015260248101919091527f73776170206d7573742068617665206265656e20696e6974696174656420667260448201527f6f6d207468697320636861696e20696e206f7264657220746f20726566756e646064820152608401610742565b60408051610140810182528254815260018301546020820152600283015491810191909152600382015460ff808216151560608401526101008083048216151560808501526201000083048216151560a0850152630100000083048216151560c08501526401000000008304909116151560e0840152600160281b9091046001600160a01b03169082015260048201546101208201526114e190611da4565b6003818101805462ff00001916620100001790819055905460048084015460405163a9059cbb60e01b81526001600160a01b03600160281b909504851692810192909252602482015291169063a9059cbb90604401602060405180830381600087803b15801561155057600080fd5b505af1158015611564573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115889190612026565b506003810154600482015460408051600160281b9093046001600160a01b03168352602083019190915283917f6e4038e4e259d4582fb84bcdf48e58d406d9322900286ea8cde6e36f94bbc32c910160405180910390a25050565b6000546001600160a01b031633148061160657506004546001600160a01b031633145b6116675760405162461bcd60e51b815260206004820152602c60248201527f73657441637469766553746174652075736572206d75737420626520636f6e7460448201526b3930b1ba1031b932b0ba37b960a11b6064820152608401610742565b6009805460ff1916911515919091179055565b6000546001600160a01b031633146116a45760405162461bcd60e51b81526004016107429061213d565b600855565b6000546001600160a01b031633146116d35760405162461bcd60e51b81526004016107429061213d565b6000546001600160a01b03166001600160a01b03164760405160006040518083038185875af1925050503d8060008114611729576040519150601f19603f3d011682016040523d82523d6000602084013e505050565b505050565b600954600090819060ff166117555760405162461bcd60e51b815260040161074290612172565b6008543410156117cd5760405162461bcd60e51b815260206004820152603d60248201527f796f75206d75737420616c736f2073656e6420656e6f7567682067617320746f60448201527f20636f7665722074686520746172676574207472616e73616374696f6e0000006064820152608401610742565b60065415806117de57506006548311155b6118395760405162461bcd60e51b815260206004820152602660248201527f747279696e6720746f2073656e64206d6f7265207468616e206d617853776170604482015265105b5bdd5b9d60d21b6064820152608401610742565b611844600854611f24565b600854156118a3576005546008546040516001600160a01b0390921691600081818185875af1925050503d806000811461189a576040519150601f19603f3d011682016040523d82523d6000602084013e61189f565b606091505b5050505b6003546040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156118f557600080fd5b505af1158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d9190612026565b506040516bffffffffffffffffffffffff193360601b1660208201524260348201819052605482018590529060009060029060740160408051601f198184030181529082905261197c91612104565b602060405180830381855afa158015611999573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906119bc919061205a565b9050604051806101400160405280828152602001838152602001838152602001600015158152602001600015158152602001600015158152602001600115158152602001600015158152602001336001600160a01b0316815260200186815250600a600083815260200190815260200160002060008201518160000155602082015181600101556040820151816002015560608201518160030160006101000a81548160ff02191690831515021790555060808201518160030160016101000a81548160ff02191690831515021790555060a08201518160030160026101000a81548160ff02191690831515021790555060c08201518160030160036101000a81548160ff02191690831515021790555060e08201518160030160046101000a81548160ff0219169083151502179055506101008201518160030160056101000a8154816001600160a01b0302191690836001600160a01b031602179055506101208201518160040155905050600a6000828152602001908152602001600020600b6000336001600160a01b03166001600160a01b031681526020019081526020016000206000820154816000015560018201548160010155600282015481600201556003820160009054906101000a900460ff168160030160006101000a81548160ff0219169083151502179055506003820160019054906101000a900460ff168160030160016101000a81548160ff0219169083151502179055506003820160029054906101000a900460ff168160030160026101000a81548160ff0219169083151502179055506003820160039054906101000a900460ff168160030160036101000a81548160ff0219169083151502179055506003820160049054906101000a900460ff168160030160046101000a81548160ff0219169083151502179055506003820160059054906101000a90046001600160a01b03168160030160056101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048201548160040155905050807f5a60af76681c67fc86f84213cadca54f623d74c2e0b5b43dd1a92412e238dcef833388604051611cfb939291909283526001600160a01b03919091166020830152604082015260600190565b60405180910390a294909350915050565b6000546001600160a01b03163314611d365760405162461bcd60e51b81526004016107429061213d565b6001600160a01b038116611d9b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610742565b610e4c81611ed4565b6000546001600160a01b03163314611dce5760405162461bcd60e51b81526004016107429061213d565b60008160200151118015611de757506000816101200151115b611e335760405162461bcd60e51b815260206004820152601860248201527f7377617020646f6573206e6f74206578697374207965742e00000000000000006044820152606401610742565b8060800151158015611e4757508060a00151155b8015611e5457508060e001515b610e4c5760405162461bcd60e51b815260206004820152604560248201527f737761702068617320616c7265616479206265656e20636f6d706c657465642c60448201527f20726566756e6465642c206f722067617320686173206e6f74206265656e20666064820152641d5b99195960da1b608482015260a401610742565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6002546001600160a01b031663d9e30e55611f3f83346122e8565b60025460405160e084901b6001600160e01b0319168152336004820152600160a01b90910460ff1660248201526044016000604051808303818588803b158015611f8857600080fd5b505af1158015611f9c573d6000803e3d6000fd5b505050505050565b80356001600160a01b0381168114611fbb57600080fd5b919050565b600060208284031215611fd1578081fd5b611fda82611fa4565b9392505050565b60008060408385031215611ff3578081fd5b611ffc83611fa4565b946020939093013593505050565b60006020828403121561201b578081fd5b8135611fda81612315565b600060208284031215612037578081fd5b8151611fda81612315565b600060208284031215612053578081fd5b5035919050565b60006020828403121561206b578081fd5b5051919050565b60008060408385031215612084578182fd5b82359150602083013561209681612315565b809150509250929050565b6000806000606084860312156120b5578081fd5b505081359360208301359350604090920135919050565b6000602082840312156120dd578081fd5b8135611fda81612323565b6000602082840312156120f9578081fd5b8151611fda81612323565b60008251815b81811015612124576020818601810151858301520161210a565b818111156121325782828501525b509190910192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526027908201527f746869732061746f6d6963207377617020696e7374616e6365206973206e6f746040820152662061637469766560c81b606082015260800190565b6000826121d457634e487b7160e01b81526012600452602481fd5b500490565b600181815b808511156122145781600019048211156121fa576121fa6122ff565b8085161561220757918102915b93841c93908002906121de565b509250929050565b6000611fda60ff841683600082612235575060016122c3565b81612242575060006122c3565b816001811461225857600281146122625761227e565b60019150506122c3565b60ff841115612273576122736122ff565b50506001821b6122c3565b5060208310610133831016604e8410600b84101617156122a1575081810a6122c3565b6122ab83836121d9565b80600019048211156122bf576122bf6122ff565b0290505b92915050565b60008160001904831182151516156122e3576122e36122ff565b500290565b6000828210156122fa576122fa6122ff565b500390565b634e487b7160e01b600052601160045260246000fd5b8015158114610e4c57600080fd5b60ff81168114610e4c57600080fdfea164736f6c6343000804000a

Verified Source Code Partial Match

Compiler: v0.8.4+commit.c7e474f2 EVM: istanbul Optimization: Yes (200 runs)
OKLGProduct.sol 54 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import '@openzeppelin/contracts/interfaces/IERC20.sol';
import './interfaces/IOKLGSpend.sol';
import './OKLGWithdrawable.sol';

/**
 * @title OKLGProduct
 * @dev Contract that every product developed in the OKLG ecosystem should implement
 */
contract OKLGProduct is OKLGWithdrawable {
  IERC20 private _token; // OKLG
  IOKLGSpend private _spend;

  uint8 public productID;

  constructor(
    uint8 _productID,
    address _tokenAddy,
    address _spendAddy
  ) {
    productID = _productID;
    _token = IERC20(_tokenAddy);
    _spend = IOKLGSpend(_spendAddy);
  }

  function setTokenAddy(address _tokenAddy) external onlyOwner {
    _token = IERC20(_tokenAddy);
  }

  function setSpendAddy(address _spendAddy) external onlyOwner {
    _spend = IOKLGSpend(_spendAddy);
  }

  function setProductID(uint8 _newId) external onlyOwner {
    productID = _newId;
  }

  function getTokenAddress() public view returns (address) {
    return address(_token);
  }

  function getSpendAddress() public view returns (address) {
    return address(_spend);
  }

  function _payForService(uint256 _weiToRemoveFromSpend) internal {
    _spend.spendOnProduct{ value: msg.value - _weiToRemoveFromSpend }(
      msg.sender,
      productID
    );
  }
}
OKLGWithdrawable.sol 25 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/interfaces/IERC20.sol';

/**
 * @title OKLGWithdrawable
 * @dev Supports being able to get tokens or ETH out of a contract with ease
 */
contract OKLGWithdrawable is Ownable {
  function withdrawTokens(address _tokenAddy, uint256 _amount)
    external
    onlyOwner
  {
    IERC20 _token = IERC20(_tokenAddy);
    _amount = _amount > 0 ? _amount : _token.balanceOf(address(this));
    require(_amount > 0, 'make sure there is a balance available to withdraw');
    _token.transfer(owner(), _amount);
  }

  function withdrawETH() external onlyOwner {
    payable(owner()).call{ value: address(this).balance }('');
  }
}
IOKLGSpend.sol 10 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @title IOKLGSpend
 * @dev Logic for spending OKLG on products in the product ecosystem.
 */
interface IOKLGSpend {
  function spendOnProduct(address _payor, uint8 _product) external payable;
}
OKLGAtomicSwapInstance.sol 275 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import '@openzeppelin/contracts/interfaces/IERC20.sol';
import './OKLGProduct.sol';

interface IERC20Decimals is IERC20 {
  function decimals() external view returns (uint8);
}

/**
 * @title OKLGAtomicSwapInstance
 * @dev This is the main contract that supports holding metadata for OKLG atomic inter and intrachain swapping
 */
contract OKLGAtomicSwapInstance is OKLGProduct {
  IERC20Decimals private _token;

  address public tokenOwner;
  address payable public oracleAddress;
  uint256 public maxSwapAmount;
  uint8 public targetTokenDecimals;
  uint256 public minimumGasForOperation = 2 * 10**15; // 2 finney (0.002 ETH)
  bool public isActive = true;

  struct Swap {
    bytes32 id;
    uint256 origTimestamp;
    uint256 currentTimestamp;
    bool isOutbound;
    bool isComplete;
    bool isRefunded;
    bool isRefundable;
    bool isSendGasFunded;
    address swapAddress;
    uint256 amount;
  }

  mapping(bytes32 => Swap) public swaps;
  mapping(address => Swap) public lastUserSwap;

  event ReceiveTokensFromSource(
    bytes32 indexed id,
    uint256 origTimestamp,
    address sender,
    uint256 amount
  );

  event SendTokensToDestination(
    bytes32 indexed id,
    address receiver,
    uint256 amount
  );

  event RefundTokensToSource(
    bytes32 indexed id,
    address sender,
    uint256 amount
  );

  event TokenOwnerUpdated(address previousOwner, address newOwner);

  constructor(
    address _costToken,
    address _spendAddress,
    address _oracleAddress,
    address _tokenOwner,
    address _tokenAddy,
    uint8 _targetTokenDecimals,
    uint256 _maxSwapAmount
  ) OKLGProduct(uint8(7), _costToken, _spendAddress) {
    oracleAddress = payable(_oracleAddress);
    tokenOwner = _tokenOwner;
    maxSwapAmount = _maxSwapAmount;
    targetTokenDecimals = _targetTokenDecimals;
    _token = IERC20Decimals(_tokenAddy);
  }

  function getSwapTokenAddress() external view returns (address) {
    return address(_token);
  }

  function setActiveState(bool _isActive) external {
    require(
      msg.sender == owner() || msg.sender == tokenOwner,
      'setActiveState user must be contract creator'
    );
    isActive = _isActive;
  }

  function setOracleAddress(address _oracleAddress) external onlyOwner {
    oracleAddress = payable(_oracleAddress);
    transferOwnership(oracleAddress);
  }

  function setTargetTokenDecimals(uint8 _decimals) external onlyOwner {
    targetTokenDecimals = _decimals;
  }

  function setTokenOwner(address newOwner) external {
    require(
      msg.sender == tokenOwner,
      'user must be current token owner to change it'
    );
    address previousOwner = tokenOwner;
    tokenOwner = newOwner;
    emit TokenOwnerUpdated(previousOwner, newOwner);
  }

  function withdrawTokens(uint256 _amount) external {
    require(
      msg.sender == tokenOwner,
      'withdrawTokens user must be token owner'
    );
    _token.transfer(msg.sender, _amount);
  }

  function setSwapCompletionStatus(bytes32 _id, bool _isComplete)
    external
    onlyOwner
  {
    swaps[_id].isComplete = _isComplete;
  }

  function setMinimumGasForOperation(uint256 _amountGas) external onlyOwner {
    minimumGasForOperation = _amountGas;
  }

  function receiveTokensFromSource(uint256 _amount)
    external
    payable
    returns (bytes32, uint256)
  {
    require(isActive, 'this atomic swap instance is not active');
    require(
      msg.value >= minimumGasForOperation,
      'you must also send enough gas to cover the target transaction'
    );
    require(
      maxSwapAmount == 0 || _amount <= maxSwapAmount,
      'trying to send more than maxSwapAmount'
    );

    _payForService(minimumGasForOperation);

    if (minimumGasForOperation > 0) {
      oracleAddress.call{ value: minimumGasForOperation }('');
    }
    _token.transferFrom(msg.sender, address(this), _amount);

    uint256 _ts = block.timestamp;
    bytes32 _id = sha256(abi.encodePacked(msg.sender, _ts, _amount));
    swaps[_id] = Swap({
      id: _id,
      origTimestamp: _ts,
      currentTimestamp: _ts,
      isOutbound: false,
      isComplete: false,
      isRefunded: false,
      isRefundable: true,
      isSendGasFunded: false,
      swapAddress: msg.sender,
      amount: _amount
    });
    lastUserSwap[msg.sender] = swaps[_id];
    emit ReceiveTokensFromSource(_id, _ts, msg.sender, _amount);
    return (_id, _ts);
  }

  function unsetLastUserSwap(address _addy) external onlyOwner {
    delete lastUserSwap[_addy];
  }

  // msg.sender must be the user who originally created the swap.
  // Otherwise, the unique identifier will not match from the originally
  // sending txn.
  //
  // NOTE: We're aware this function can be spoofed by creating a sha256 hash of msg.sender's address
  // and _origTimestamp, but it's important to note refundTokensFromSource and sendTokensToDestination
  // can only be executed by the owner/oracle. Therefore validation should be done by the oracle before
  // executing those and the only possibility of a vulnerability is if someone has compromised the oracle account.
  function fundSendToDestinationGas(
    bytes32 _id,
    uint256 _origTimestamp,
    uint256 _amount
  ) external payable {
    require(
      msg.value >= minimumGasForOperation,
      'you must send enough gas to cover the send transaction'
    );
    require(
      _id == sha256(abi.encodePacked(msg.sender, _origTimestamp, _amount)),
      'we do not recognize this swap'
    );
    require(!swaps[_id].isSendGasFunded, 'cannot fund swap again');
    if (minimumGasForOperation > 0) {
      oracleAddress.call{ value: minimumGasForOperation }('');
    }
    swaps[_id] = Swap({
      id: _id,
      origTimestamp: _origTimestamp,
      currentTimestamp: block.timestamp,
      isOutbound: true,
      isComplete: swaps[_id].isComplete,
      isRefunded: swaps[_id].isRefunded,
      isRefundable: swaps[_id].isRefundable,
      isSendGasFunded: true,
      swapAddress: msg.sender,
      amount: _amount
    });
  }

  // This must be called AFTER fundSendToDestinationGas has been executed
  // for this txn to fund this send operation
  function refundTokensFromSource(bytes32 _id) external {
    require(isActive, 'this atomic swap instance is not active');

    Swap storage swap = swaps[_id];
    require(
      swap.isRefundable,
      'swap must have been initiated from this chain in order to refund'
    );

    _confirmSwapExistsGasFundedAndSenderValid(swap);
    swap.isRefunded = true;
    _token.transfer(swap.swapAddress, swap.amount);
    emit RefundTokensToSource(_id, swap.swapAddress, swap.amount);
  }

  // This must be called AFTER fundSendToDestinationGas has been executed
  // for this txn to fund this send operation
  function sendTokensToDestination(bytes32 _id) external returns (bytes32) {
    require(isActive, 'this atomic swap instance is not active');

    Swap storage swap = swaps[_id];

    _confirmSwapExistsGasFundedAndSenderValid(swap);

    // handle if this token and target chain token in bridge have different decimals
    // current decimals = 9 -- 100 tokens == 100000000000
    // target decimals = 18 -- 100 tokens == 100000000000000000000
    // to get current amount to transfer, need to multiply by ratio of 10^currentDecimals / 10^targetDecimals
    uint256 _swapAmount = swap.amount;
    if (targetTokenDecimals > 0) {
      _swapAmount =
        (_swapAmount * 10**_token.decimals()) /
        10**targetTokenDecimals;
    }
    _token.transfer(swap.swapAddress, _swapAmount);

    swap.currentTimestamp = block.timestamp;
    swap.isComplete = true;
    emit SendTokensToDestination(_id, swap.swapAddress, _swapAmount);
    return _id;
  }

  function _confirmSwapExistsGasFundedAndSenderValid(Swap memory swap)
    private
    view
    onlyOwner
  {
    // functions that call this should only be called by the current owner
    // or oracle address as they will do the appropriate validation beforehand
    // to confirm the receiving swap is valid before sending tokens to the user.
    require(
      swap.origTimestamp > 0 && swap.amount > 0,
      'swap does not exist yet.'
    );
    // We're just validating here that the swap has not been
    // completed and gas has been funded before moving forward.
    require(
      !swap.isComplete && !swap.isRefunded && swap.isSendGasFunded,
      'swap has already been completed, refunded, or gas has not been funded'
    );
  }
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
Ownable.sol 76 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
IERC20.sol 6 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

Read Contract

getSpendAddress 0xdc3aaab5 → address
getSwapTokenAddress 0xeba760d6 → address
getTokenAddress 0x10fe9ae8 → address
isActive 0x22f3e2d4 → bool
lastUserSwap 0x933a59db → bytes32, uint256, uint256, bool, bool, bool, bool, bool, address, uint256
maxSwapAmount 0xcce987d4 → uint256
minimumGasForOperation 0x8d17359e → uint256
oracleAddress 0xa89ae4ba → address
owner 0x8da5cb5b → address
productID 0xf9fb452f → uint8
swaps 0xeb84e7f2 → bytes32, uint256, uint256, bool, bool, bool, bool, bool, address, uint256
targetTokenDecimals 0xad701278 → uint8
tokenOwner 0xa3e67610 → address

Write Contract 19 functions

These functions modify contract state and require a wallet transaction to execute.

fundSendToDestinationGas 0x8a2e386e
bytes32 _id
uint256 _origTimestamp
uint256 _amount
receiveTokensFromSource 0xed8f584b
uint256 _amount
returns: bytes32, uint256
refundTokensFromSource 0xa1734e60
bytes32 _id
renounceOwnership 0x715018a6
No parameters
sendTokensToDestination 0x1028e492
bytes32 _id
returns: bytes32
setActiveState 0xbfe22a01
bool _isActive
setMinimumGasForOperation 0xcd41ced0
uint256 _amountGas
setOracleAddress 0x4c69c00f
address _oracleAddress
setProductID 0x9e9f695d
uint8 _newId
setSpendAddy 0x7c0bf7bb
address _spendAddy
setSwapCompletionStatus 0x565e6d1c
bytes32 _id
bool _isComplete
setTargetTokenDecimals 0xa06bbf08
uint8 _decimals
setTokenAddy 0x4bc10ccb
address _tokenAddy
setTokenOwner 0x18e02bd9
address newOwner
transferOwnership 0xf2fde38b
address newOwner
unsetLastUserSwap 0x113d4e1e
address _addy
withdrawETH 0xe086e5ec
No parameters
withdrawTokens 0x06b091f9
address _tokenAddy
uint256 _amount
withdrawTokens 0x315a095d
uint256 _amount

Recent Transactions

No transactions found for this address