-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathPolyWrapper_v2.sol
More file actions
113 lines (88 loc) · 3.96 KB
/
PolyWrapper_v2.sol
File metadata and controls
113 lines (88 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.6.0;
import "./libs/token/ERC20/SafeERC20.sol";
import "./libs/token/ERC20/IERC20.sol";
import "./libs/access/Ownable.sol";
import "./libs/utils/ReentrancyGuard.sol";
import "./libs/math/SafeMath.sol";
import "./libs/lifecycle/Pausable.sol";
import "./interfaces/ILockProxy.sol";
contract PolyWrapperV2 is Ownable, Pausable, ReentrancyGuard {
using SafeMath for uint;
using SafeERC20 for IERC20;
uint public chainId;
address public feeCollector;
ILockProxy public lockProxy;
constructor(address _owner, uint _chainId) public {
require(_chainId != 0, "!legal");
transferOwnership(_owner);
chainId = _chainId;
}
function setFeeCollector(address collector) external onlyOwner {
require(collector != address(0), "emtpy address");
feeCollector = collector;
}
function setLockProxy(address _lockProxy) external onlyOwner {
require(_lockProxy != address(0));
lockProxy = ILockProxy(_lockProxy);
require(lockProxy.managerProxyContract() != address(0), "not lockproxy");
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function extractFee(address token) external {
require(msg.sender == feeCollector, "!feeCollector");
if (token == address(0)) {
payable(msg.sender).transfer(address(this).balance);
} else {
IERC20(token).safeTransfer(feeCollector, IERC20(token).balanceOf(address(this)));
}
}
function lock(address fromAsset, uint64 toChainId, bytes memory toAddress, uint amount, uint fee, uint id) external payable nonReentrant whenNotPaused {
require(toChainId != chainId && toChainId != 0, "!toChainId");
require(toAddress.length !=0, "empty toAddress");
address addr;
assembly { addr := mload(add(toAddress,0x14)) }
require(addr != address(0),"zero toAddress");
_pull(fromAsset, amount);
amount = _checkoutFee(fromAsset, amount, fee);
_push(fromAsset, toChainId, toAddress, amount);
emit PolyWrapperLock(fromAsset, msg.sender, toChainId, toAddress, amount, fee, id);
}
function speedUp(address fromAsset, bytes memory txHash, uint fee) external payable nonReentrant whenNotPaused {
_pull(fromAsset, fee);
emit PolyWrapperSpeedUp(fromAsset, txHash, msg.sender, fee);
}
function _pull(address fromAsset, uint amount) internal {
if (fromAsset == address(0)) {
require(msg.value == amount, "insufficient ether");
} else {
IERC20(fromAsset).safeTransferFrom(msg.sender, address(this), amount);
}
}
// take fee in the form of ether
function _checkoutFee(address fromAsset, uint amount, uint fee) internal view returns (uint) {
if (fromAsset == address(0)) {
require(msg.value >= amount, "insufficient ether");
require(amount > fee, "amount less than fee");
return amount.sub(fee);
} else {
require(msg.value >= fee, "insufficient ether");
return amount;
}
}
function _push(address fromAsset, uint64 toChainId, bytes memory toAddress, uint amount) internal {
if (fromAsset == address(0)) {
require(lockProxy.lock{value: amount}(fromAsset, toChainId, toAddress, amount), "lock ether fail");
} else {
IERC20(fromAsset).safeApprove(address(lockProxy), 0);
IERC20(fromAsset).safeApprove(address(lockProxy), amount);
require(lockProxy.lock(fromAsset, toChainId, toAddress, amount), "lock erc20 fail");
}
}
event PolyWrapperLock(address indexed fromAsset, address indexed sender, uint64 toChainId, bytes toAddress, uint net, uint fee, uint id);
event PolyWrapperSpeedUp(address indexed fromAsset, bytes indexed txHash, address indexed sender, uint efee);
}