Overview
POL Balance
0 POL
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 30,974 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Settle Promise | 14323789 | 31 days ago | IN | 0 POL | 0.00302098 | ||||
Settle With Bene... | 14323095 | 31 days ago | IN | 0 POL | 0.00414832 | ||||
Settle With Bene... | 14322854 | 31 days ago | IN | 0 POL | 0.00414857 | ||||
Settle Promise | 14322854 | 31 days ago | IN | 0 POL | 0.0036199 | ||||
Settle Promise | 14322613 | 31 days ago | IN | 0 POL | 0.00362052 | ||||
Settle Promise | 14322580 | 31 days ago | IN | 0 POL | 0.0036199 | ||||
Settle Promise | 14322373 | 31 days ago | IN | 0 POL | 0.00302122 | ||||
Settle Promise | 14321224 | 31 days ago | IN | 0 POL | 0.00361915 | ||||
Settle Promise | 14320529 | 31 days ago | IN | 0 POL | 0.00361841 | ||||
Settle With Bene... | 14320529 | 31 days ago | IN | 0 POL | 0.00414832 | ||||
Settle Promise | 14320288 | 31 days ago | IN | 0 POL | 0.00361952 | ||||
Settle With Bene... | 14320288 | 31 days ago | IN | 0 POL | 0.00414832 | ||||
Settle Promise | 14319594 | 31 days ago | IN | 0 POL | 0.00361952 | ||||
Settle Promise | 14319593 | 31 days ago | IN | 0 POL | 0.0030206 | ||||
Settle Promise | 14319352 | 31 days ago | IN | 0 POL | 0.00361952 | ||||
Settle With Bene... | 14318657 | 31 days ago | IN | 0 POL | 0.0669065 | ||||
Settle With Bene... | 14317964 | 31 days ago | IN | 0 POL | 0.00414857 | ||||
Settle Promise | 14317724 | 31 days ago | IN | 0 POL | 0.00362052 | ||||
Settle With Bene... | 14317724 | 31 days ago | IN | 0 POL | 0.00414795 | ||||
Settle Promise | 14317436 | 31 days ago | IN | 0 POL | 0.00361952 | ||||
Settle Promise | 14316348 | 31 days ago | IN | 0 POL | 0.00362014 | ||||
Settle With Bene... | 14315653 | 31 days ago | IN | 0 POL | 0.00414696 | ||||
Settle Promise | 14315412 | 31 days ago | IN | 0 POL | 0.00302098 | ||||
Settle Promise | 14315411 | 31 days ago | IN | 0 POL | 0.0036199 | ||||
Settle With Bene... | 14315139 | 31 days ago | IN | 0 POL | 0.00149519 |
Latest 9 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6324636 | 230 days ago | Contract Creation | 0 POL | |||
6324363 | 230 days ago | Contract Creation | 0 POL | |||
6323663 | 230 days ago | Contract Creation | 0 POL | |||
6323641 | 230 days ago | Contract Creation | 0 POL | |||
6322623 | 230 days ago | Contract Creation | 0 POL | |||
6322425 | 230 days ago | Contract Creation | 0 POL | |||
6322402 | 230 days ago | Contract Creation | 0 POL | |||
6321905 | 230 days ago | Contract Creation | 0 POL | |||
6321893 | 230 days ago | Contract Creation | 0 POL |
Loading...
Loading
Minimal Proxy Contract for 0x9e75de5594fddbc641d4cd62c2acad781b2a35d0
Contract Name:
HermesImplementation
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import { IUniswapV2Router } from "./interfaces/IUniswapV2Router.sol"; import { IERC20Token } from "./interfaces/IERC20Token.sol"; import { FundsRecovery } from "./FundsRecovery.sol"; import { Utils } from "./Utils.sol"; interface IdentityRegistry { function isRegistered(address _identity) external view returns (bool); function minimalHermesStake() external view returns (uint256); function getChannelAddress(address _identity, address _hermesId) external view returns (address); function getBeneficiary(address _identity) external view returns (address); function setBeneficiary(address _identity, address _newBeneficiary, bytes memory _signature) external; } // Hermes (channel balance provided by Herms, no staking/loans) contract HermesImplementation is FundsRecovery, Utils { using ECDSA for bytes32; string constant STAKE_RETURN_PREFIX = "Stake return request"; uint256 constant DELAY_SECONDS = 259200; // 3 days uint256 constant UNIT_SECONDS = 3600; // 1 unit = 1 hour = 3600 seconds uint16 constant PUNISHMENT_PERCENT = 4; // 0.04% IdentityRegistry internal registry; address internal operator; // TODO have master operator who could change operator or manage funds uint256 internal totalStake; // total amount staked by providers uint256 internal minStake; // minimal possible provider's stake (channel opening during promise settlement will use it) uint256 internal maxStake; // maximal allowed provider's stake uint256 internal hermesStake; // hermes stake is used to prove hermes' sustainability uint256 internal closingTimelock; // blocknumber after which getting stake back will become possible IUniswapV2Router internal dex; // any uniswap v2 compatible dex router address enum Status { Active, Paused, Punishment, Closed } // hermes states Status internal status; struct HermesFee { uint16 value; // subprocent amount. e.g. 2.5% = 250 uint64 validFrom; // timestamp from which fee is valid } HermesFee public lastFee; // default fee to look for HermesFee public previousFee; // previous fee is used if last fee is still not active // Our channel don't have balance, because we're always rebalancing into stake amount. struct Channel { uint256 settled; // total amount already settled by provider uint256 stake; // amount staked by identity to guarante channel size, it also serves as channel balance uint256 lastUsedNonce; // last known nonce, is used to protect signature based calls from replay attack uint256 timelock; // blocknumber after which channel balance can be decreased } mapping(bytes32 => Channel) public channels; struct Punishment { uint256 activationBlockTime; // block timestamp in which punishment was activated uint256 amount; // total amount of tokens locked because of punishment } Punishment public punishment; function getOperator() public view returns (address) { return operator; } function getChannelId(address _identity) public view returns (bytes32) { return keccak256(abi.encodePacked(_identity, address(this))); } function getChannelId(address _identity, string memory _type) public view returns (bytes32) { return keccak256(abi.encodePacked(_identity, address(this), _type)); } function getRegistry() public view returns (address) { return address(registry); } function getActiveFee() public view returns (uint256) { HermesFee memory _activeFee = (block.timestamp >= lastFee.validFrom) ? lastFee : previousFee; return uint256(_activeFee.value); } function getHermesStake() public view returns (uint256) { return hermesStake; } function getStakeThresholds() public view returns (uint256, uint256) { return (minStake, maxStake); } // Returns hermes state // Active - all operations are allowed. // Paused - no new channel openings. // Punishment - don't allow to open new channels, rebalance and withdraw funds. // Closed - no new channels, no rebalance, no stake increase. function getStatus() public view returns (Status) { return status; } event PromiseSettled(address indexed identity, bytes32 indexed channelId, address indexed beneficiary, uint256 amountSentToBeneficiary, uint256 fees, bytes32 lock); event NewStake(bytes32 indexed channelId, uint256 stakeAmount); event MinStakeValueUpdated(uint256 newMinStake); event MaxStakeValueUpdated(uint256 newMaxStake); event HermesFeeUpdated(uint16 newFee, uint64 validFrom); event HermesClosed(uint256 blockTimestamp); event ChannelOpeningPaused(); event ChannelOpeningActivated(); event FundsWithdrawned(uint256 amount, address beneficiary); event HermesStakeIncreased(uint256 newStake); event HermesPunishmentActivated(uint256 activationBlockTime); event HermesPunishmentDeactivated(); modifier onlyOperator() { require(msg.sender == operator, "Hermes: only hermes operator can call this function"); _; } /* ------------------------------------------- SETUP ------------------------------------------- */ // Because of proxy pattern this function is used insted of constructor. // Have to be called right after proxy deployment. function initialize(address _token, address _operator, uint16 _fee, uint256 _minStake, uint256 _maxStake, address payable _dexAddress) public virtual { require(!isInitialized(), "Hermes: have to be not initialized"); require(_token != address(0), "Hermes: token can't be deployd into zero address"); require(_operator != address(0), "Hermes: operator have to be set"); require(_fee <= 5000, "Hermes: fee can't be bigger than 50%"); require(_maxStake > _minStake, "Hermes: maxStake have to be bigger than minStake"); registry = IdentityRegistry(msg.sender); token = IERC20Token(_token); operator = _operator; lastFee = HermesFee(_fee, uint64(block.timestamp)); minStake = _minStake; maxStake = _maxStake; hermesStake = token.balanceOf(address(this)); // Approving all myst for dex, because MYST token's `transferFrom` is cheaper when there is approval of uint(-1) token.approve(_dexAddress, type(uint256).max); dex = IUniswapV2Router(_dexAddress); transferOwnership(_operator); } function isInitialized() public view returns (bool) { return operator != address(0); } /* -------------------------------------- MAIN FUNCTIONALITY ----------------------------------- */ // Open incoming payments (also known as provider) channel. Can be called only by Registry. function openChannel(address _identity, uint256 _amountToStake) public { require(msg.sender == address(registry), "Hermes: only registry can open channels"); require(getStatus() == Status.Active, "Hermes: have to be in active state"); require(_amountToStake >= minStake, "Hermes: min stake amount not reached"); _increaseStake(getChannelId(_identity), _amountToStake, false); } // Settle promise // _preimage is random number generated by receiver used in HTLC function _settlePromise( bytes32 _channelId, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature, bool _takeFee, bool _ignoreStake ) private returns (uint256, uint256) { require( isHermesActive(), "Hermes: hermes have to be in active state" ); // if hermes is not active, then users can only take stake back require( validatePromise(_channelId, _amount, _transactorFee, _preimage, _signature), "Hermes: have to be properly signed payment promise" ); Channel storage _channel = channels[_channelId]; require(_channel.settled > 0 || _channel.stake >= minStake || _ignoreStake, "Hermes: not enough stake"); // If there are not enought funds to rebalance we have to enable punishment mode. uint256 _availableBalance = availableBalance(); if (_availableBalance < _channel.stake) { status = Status.Punishment; punishment.activationBlockTime = block.timestamp; emit HermesPunishmentActivated(block.timestamp); } // Calculate amount of tokens to be claimed. uint256 _unpaidAmount = _amount - _channel.settled; require(_unpaidAmount > _transactorFee, "Hermes: amount to settle should cover transactor fee"); // It is not allowed to settle more than maxStake / _channel.stake and than available balance. uint256 _maxSettlementAmount = max(maxStake, _channel.stake); if (_unpaidAmount > _availableBalance || _unpaidAmount > _maxSettlementAmount) { _unpaidAmount = min(_availableBalance, _maxSettlementAmount); } _channel.settled = _channel.settled + _unpaidAmount; // Increase already paid amount. uint256 _fees = _transactorFee + (_takeFee ? calculateHermesFee(_unpaidAmount) : 0); // Pay transactor fee if (_transactorFee > 0) { token.transfer(msg.sender, _transactorFee); } uint256 _amountToTransfer = _unpaidAmount -_fees; return (_amountToTransfer, _fees); } function settlePromise(address _identity, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature) public { address _beneficiary = registry.getBeneficiary(_identity); require(_beneficiary != address(0), "Hermes: identity have to be registered, beneficiary have to be set"); // Settle promise and transfer calculated amount into beneficiary wallet bytes32 _channelId = getChannelId(_identity); (uint256 _amountToTransfer, uint256 _fees) = _settlePromise(_channelId, _amount, _transactorFee, _preimage, _signature, true, false); token.transfer(_beneficiary, _amountToTransfer); emit PromiseSettled(_identity, _channelId, _beneficiary, _amountToTransfer, _fees, _preimage); } function payAndSettle(address _identity, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature, address _beneficiary, bytes memory _beneficiarySignature) public { bytes32 _channelId = getChannelId(_identity, "withdrawal"); // Validate beneficiary to be signed by identity and be attached to given promise address _signer = keccak256(abi.encodePacked(getChainID(), _channelId, _amount, _preimage, _beneficiary)).recover(_beneficiarySignature); require(_signer == _identity, "Hermes: payAndSettle request should be properly signed"); (uint256 _amountToTransfer, uint256 _fees) = _settlePromise(_channelId, _amount, _transactorFee, _preimage, _signature, false, true); token.transfer(_beneficiary, _amountToTransfer); emit PromiseSettled(_identity, _channelId, _beneficiary, _amountToTransfer, _fees, _preimage); } function settleWithBeneficiary(address _identity, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _promiseSignature, address _newBeneficiary, bytes memory _beneficiarySignature) public { // Update beneficiary address registry.setBeneficiary(_identity, _newBeneficiary, _beneficiarySignature); // Settle promise and transfer calculated amount into beneficiary wallet bytes32 _channelId = getChannelId(_identity); (uint256 _amountToTransfer, uint256 _fees) = _settlePromise(_channelId, _amount, _transactorFee, _preimage, _promiseSignature, true, false); token.transfer(_newBeneficiary, _amountToTransfer); emit PromiseSettled(_identity, _channelId, _newBeneficiary, _amountToTransfer, _fees, _preimage); } function settleWithDEX(address _identity, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature) public { address _beneficiary = registry.getBeneficiary(_identity); require(_beneficiary != address(0), "Hermes: identity have to be registered, beneficiary have to be set"); // Calculate amount to transfer and settle promise bytes32 _channelId = getChannelId(_identity); (uint256 _amountToTransfer, uint256 _fees) = _settlePromise(_channelId, _amount, _transactorFee, _preimage, _signature, true, false); // Transfer funds into beneficiary wallet via DEX uint amountOutMin = 0; address[] memory path = new address[](2); path[0] = address(token); path[1] = dex.WETH(); dex.swapExactTokensForETH(_amountToTransfer, amountOutMin, path, _beneficiary, block.timestamp); emit PromiseSettled(_identity, _channelId, _beneficiary, _amountToTransfer, _fees, _preimage); } /* -------------------------------------- STAKE MANAGEMENT -------------------------------------- */ function _increaseStake(bytes32 _channelId, uint256 _amountToAdd, bool _duringSettlement) internal { Channel storage _channel = channels[_channelId]; uint256 _newStakeAmount = _channel.stake +_amountToAdd; require(_newStakeAmount <= maxStake, "Hermes: total amount to stake can't be bigger than maximally allowed"); require(_newStakeAmount >= minStake, "Hermes: stake can't be less than required min stake"); // We don't transfer tokens during settlements, they already locked in hermes contract. if (!_duringSettlement) { require(token.transferFrom(msg.sender, address(this), _amountToAdd), "Hermes: token transfer should succeed"); } _channel.stake = _newStakeAmount; totalStake = totalStake + _amountToAdd; emit NewStake(_channelId, _newStakeAmount); } // Anyone can increase channel's capacity by staking more into hermes function increaseStake(bytes32 _channelId, uint256 _amount) public { require(getStatus() != Status.Closed, "hermes should be not closed"); _increaseStake(_channelId, _amount, false); } // Settlement which will increase channel stake instead of transfering funds into beneficiary wallet. function settleIntoStake(address _identity, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature) public { bytes32 _channelId = getChannelId(_identity); (uint256 _stakeIncreaseAmount, uint256 _paidFees) = _settlePromise(_channelId, _amount, _transactorFee, _preimage, _signature, true, true); emit PromiseSettled(_identity, _channelId, address(this), _stakeIncreaseAmount, _paidFees, _preimage); _increaseStake(_channelId, _stakeIncreaseAmount, true); } // Withdraw part of stake. This will also decrease channel balance. function decreaseStake(address _identity, uint256 _amount, uint256 _transactorFee, bytes memory _signature) public { bytes32 _channelId = getChannelId(_identity); require(isChannelOpened(_channelId), "Hermes: channel has to be opened"); require(_amount >= _transactorFee, "Hermes: amount should be bigger than transactor fee"); Channel storage _channel = channels[_channelId]; require(_amount <= _channel.stake, "Hermes: can't withdraw more than the current stake"); // Verify signature _channel.lastUsedNonce = _channel.lastUsedNonce + 1; address _signer = keccak256(abi.encodePacked(STAKE_RETURN_PREFIX, getChainID(), _channelId, _amount, _transactorFee, _channel.lastUsedNonce)).recover(_signature); require(getChannelId(_signer) == _channelId, "Hermes: have to be signed by channel party"); uint256 _newStakeAmount = _channel.stake - _amount; require(_newStakeAmount == 0 || _newStakeAmount >= minStake, "Hermes: stake can't be less than required min stake"); // Update channel state _channel.stake = _newStakeAmount; totalStake = totalStake - _amount; // Pay transacor fee then withdraw the rest if (_transactorFee > 0) { token.transfer(msg.sender, _transactorFee); } address _beneficiary = registry.getBeneficiary(_identity); token.transfer(_beneficiary, _amount - _transactorFee); emit NewStake(_channelId, _newStakeAmount); } /* --------------------------------------------------------------------------------------------- */ // Hermes is in Emergency situation when its status is `Punishment`. function resolveEmergency() public { require(getStatus() == Status.Punishment, "Hermes: should be in punishment status"); // 0.04% of total channels amount per time unit uint256 _punishmentPerUnit = round(totalStake * PUNISHMENT_PERCENT, 100) / 100; // No punishment during first time unit uint256 _unit = getUnitTime(); uint256 _timePassed = block.timestamp - punishment.activationBlockTime; uint256 _punishmentUnits = round(_timePassed, _unit) / _unit - 1; uint256 _punishmentAmount = _punishmentUnits * _punishmentPerUnit; punishment.amount = punishment.amount + _punishmentAmount; // XXX alternativelly we could send tokens into BlackHole (0x0000000...) uint256 _shouldHave = minimalExpectedBalance() + maxStake; // hermes should have funds for at least one maxStake settlement uint256 _currentBalance = token.balanceOf(address(this)); // If there are not enough available funds, they have to be topuped from msg.sender. if (_currentBalance < _shouldHave) { token.transferFrom(msg.sender, address(this), _shouldHave - _currentBalance); } // Disable punishment mode status = Status.Active; emit HermesPunishmentDeactivated(); } function getUnitTime() internal pure virtual returns (uint256) { return UNIT_SECONDS; } function setMinStake(uint256 _newMinStake) public onlyOwner { require(isHermesActive(), "Hermes: has to be active"); require(_newMinStake < maxStake, "Hermes: minStake has to be smaller than maxStake"); minStake = _newMinStake; emit MinStakeValueUpdated(_newMinStake); } function setMaxStake(uint256 _newMaxStake) public onlyOwner { require(isHermesActive(), "Hermes: has to be active"); require(_newMaxStake > minStake, "Hermes: maxStake has to be bigger than minStake"); maxStake = _newMaxStake; emit MaxStakeValueUpdated(_newMaxStake); } function setHermesFee(uint16 _newFee) public onlyOwner { require(getStatus() != Status.Closed, "Hermes: should be not closed"); require(_newFee <= 5000, "Hermes: fee can't be bigger than 50%"); require(block.timestamp >= lastFee.validFrom, "Hermes: can't update inactive fee"); // New fee will start be valid after delay time will pass uint64 _validFrom = uint64(getTimelock()); previousFee = lastFee; lastFee = HermesFee(_newFee, _validFrom); emit HermesFeeUpdated(_newFee, _validFrom); } function increaseHermesStake(uint256 _additionalStake) public onlyOwner { if (availableBalance() < _additionalStake) { uint256 _diff = _additionalStake - availableBalance(); token.transferFrom(msg.sender, address(this), _diff); } hermesStake = hermesStake + _additionalStake; emit HermesStakeIncreased(hermesStake); } // Hermes's available funds withdrawal. Can be done only if hermes is not closed and not in punishment mode. // Hermes can't withdraw stake, locked in channel funds and funds lended to him. function withdraw(address _beneficiary, uint256 _amount) public onlyOwner { require(isHermesActive(), "Hermes: have to be active"); require(availableBalance() >= _amount, "Hermes: should be enough funds available to withdraw"); token.transfer(_beneficiary, _amount); emit FundsWithdrawned(_amount, _beneficiary); } // Returns funds amount not locked in any channel, not staked and not lended from providers. function availableBalance() public view returns (uint256) { uint256 _totalLockedAmount = minimalExpectedBalance(); uint256 _currentBalance = token.balanceOf(address(this)); if (_totalLockedAmount > _currentBalance) { return uint256(0); } return _currentBalance - _totalLockedAmount; } // Returns true if channel is opened. function isChannelOpened(bytes32 _channelId) public view returns (bool) { return channels[_channelId].settled != 0 || channels[_channelId].stake != 0; } // If Hermes is not closed and is not in punishment mode, he is active. function isHermesActive() public view returns (bool) { Status _status = getStatus(); return _status != Status.Punishment && _status != Status.Closed; } function pauseChannelOpening() public onlyOperator { require(getStatus() == Status.Active, "Hermes: have to be in active state"); status = Status.Paused; emit ChannelOpeningPaused(); } function activateChannelOpening() public onlyOperator { require(getStatus() == Status.Paused, "Hermes: have to be in paused state"); status = Status.Active; emit ChannelOpeningActivated(); } function closeHermes() public onlyOwner { require(isHermesActive(), "Hermes: should be active"); status = Status.Closed; closingTimelock = getEmergencyTimelock(); emit HermesClosed(block.timestamp); } function getStakeBack(address _beneficiary) public onlyOwner { require(getStatus() == Status.Closed, "Hermes: have to be closed"); require(block.timestamp > closingTimelock, "Hermes: timelock period should be already passed"); uint256 _amount = token.balanceOf(address(this)) - punishment.amount; token.transfer(_beneficiary, _amount); } /* ------------------------------------------ HELPERS ------------------------------------------ */ // Returns timestamp until which exit request should be locked function getTimelock() internal view virtual returns (uint256) { return block.timestamp + DELAY_SECONDS; } function calculateHermesFee(uint256 _amount) public view returns (uint256) { return round((_amount * getActiveFee() / 100), 100) / 100; } // Funds which always have to be holded in hermes smart contract. function minimalExpectedBalance() public view returns (uint256) { return max(hermesStake, punishment.amount) + totalStake; } function getEmergencyTimelock() internal view virtual returns (uint256) { return block.timestamp + DELAY_SECONDS * 100; // 300 days } function validatePromise(bytes32 _channelId, uint256 _amount, uint256 _transactorFee, bytes32 _preimage, bytes memory _signature) public view returns (bool) { bytes32 _hashlock = keccak256(abi.encodePacked(_preimage)); address _signer = keccak256(abi.encodePacked(getChainID(), _channelId, _amount, _transactorFee, _hashlock)).recover(_signature); return _signer == operator; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; import { IERC20Token } from "./interfaces/IERC20Token.sol"; import { Ownable } from "./Ownable.sol"; import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract FundsRecovery is Ownable, ReentrancyGuard { address payable internal fundsDestination; IERC20Token public token; event DestinationChanged(address indexed previousDestination, address indexed newDestination); /** * Setting new destination of funds recovery. */ function setFundsDestination(address payable _newDestination) public virtual onlyOwner { require(_newDestination != address(0)); emit DestinationChanged(fundsDestination, _newDestination); fundsDestination = _newDestination; } /** * Getting funds destination address. */ function getFundsDestination() public view returns (address) { return fundsDestination; } /** * Possibility to recover funds in case they were sent to this address before smart contract deployment */ function claimEthers() public nonReentrant { require(fundsDestination != address(0)); fundsDestination.transfer(address(this).balance); } /** Transfers selected tokens into owner address. */ function claimTokens(address _token) public nonReentrant { require(fundsDestination != address(0)); require(_token != address(token), "native token funds can't be recovered"); uint256 _amount = IERC20Token(_token).balanceOf(address(this)); IERC20Token(_token).transfer(fundsDestination, _amount); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(_owner == msg.sender || _owner == address(0x0), "Ownable: caller is not the owner"); _; } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; contract Utils { function getChainID() internal view returns (uint256) { uint256 chainID; assembly { chainID := chainid() } return chainID; } function max(uint a, uint b) internal pure returns (uint) { return a > b ? a : b; } function min(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } function round(uint a, uint m) internal pure returns (uint ) { return ((a + m - 1) / m) * m; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.4; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; abstract contract IERC20Token is IERC20 { function upgrade(uint256 value) public virtual; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.4; interface IUniswapV2Router { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, 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); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "london", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"anonymous":false,"inputs":[],"name":"ChannelOpeningActivated","type":"event"},{"anonymous":false,"inputs":[],"name":"ChannelOpeningPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousDestination","type":"address"},{"indexed":true,"internalType":"address","name":"newDestination","type":"address"}],"name":"DestinationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"}],"name":"FundsWithdrawned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blockTimestamp","type":"uint256"}],"name":"HermesClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"newFee","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"validFrom","type":"uint64"}],"name":"HermesFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"activationBlockTime","type":"uint256"}],"name":"HermesPunishmentActivated","type":"event"},{"anonymous":false,"inputs":[],"name":"HermesPunishmentDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newStake","type":"uint256"}],"name":"HermesStakeIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxStake","type":"uint256"}],"name":"MaxStakeValueUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinStake","type":"uint256"}],"name":"MinStakeValueUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"channelId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"stakeAmount","type":"uint256"}],"name":"NewStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"identity","type":"address"},{"indexed":true,"internalType":"bytes32","name":"channelId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountSentToBeneficiary","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"lock","type":"bytes32"}],"name":"PromiseSettled","type":"event"},{"inputs":[],"name":"activateChannelOpening","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculateHermesFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"channels","outputs":[{"internalType":"uint256","name":"settled","type":"uint256"},{"internalType":"uint256","name":"stake","type":"uint256"},{"internalType":"uint256","name":"lastUsedNonce","type":"uint256"},{"internalType":"uint256","name":"timelock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimEthers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"claimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeHermes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"decreaseStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getActiveFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"string","name":"_type","type":"string"}],"name":"getChannelId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"}],"name":"getChannelId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundsDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHermesStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"getStakeBack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getStakeThresholds","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatus","outputs":[{"internalType":"enum HermesImplementation.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_additionalStake","type":"uint256"}],"name":"increaseHermesStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_channelId","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"increaseStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"uint16","name":"_fee","type":"uint16"},{"internalType":"uint256","name":"_minStake","type":"uint256"},{"internalType":"uint256","name":"_maxStake","type":"uint256"},{"internalType":"address payable","name":"_dexAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_channelId","type":"bytes32"}],"name":"isChannelOpened","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isHermesActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFee","outputs":[{"internalType":"uint16","name":"value","type":"uint16"},{"internalType":"uint64","name":"validFrom","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimalExpectedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amountToStake","type":"uint256"}],"name":"openChannel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseChannelOpening","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"bytes","name":"_beneficiarySignature","type":"bytes"}],"name":"payAndSettle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"previousFee","outputs":[{"internalType":"uint16","name":"value","type":"uint16"},{"internalType":"uint64","name":"validFrom","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"punishment","outputs":[{"internalType":"uint256","name":"activationBlockTime","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"resolveEmergency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newDestination","type":"address"}],"name":"setFundsDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_newFee","type":"uint16"}],"name":"setHermesFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxStake","type":"uint256"}],"name":"setMaxStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMinStake","type":"uint256"}],"name":"setMinStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"settleIntoStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"settlePromise","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_promiseSignature","type":"bytes"},{"internalType":"address","name":"_newBeneficiary","type":"address"},{"internalType":"bytes","name":"_beneficiarySignature","type":"bytes"}],"name":"settleWithBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_identity","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"settleWithDEX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20Token","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_channelId","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_transactorFee","type":"uint256"},{"internalType":"bytes32","name":"_preimage","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"validatePromise","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.