-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEtherBridge.rb
115 lines (87 loc) · 3.22 KB
/
EtherBridge.rb
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
114
115
pragma :rubidity, "1.0.0"
import "ERC20"
import "Upgradeable"
contract :EtherBridge, is: [:ERC20, :Upgradeable], upgradeable: true do
event :InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 }
event :WithdrawalComplete, { to: :address, amounts: [:uint256], withdrawalIds: [:bytes32] }
address :public, :trustedSmartContract
mapping ({ address: :uint256 }), :public, :pendingWithdrawalAmounts
mapping ({ address: array(:bytes32) }), :public, :pendingUserWithdrawalIds
bool :public, :bridgeOutPaused
constructor(
name: :string,
symbol: :string,
trustedSmartContract: :address
) {
ERC20.constructor(name: name, symbol: symbol, decimals: 18)
Upgradeable.constructor(upgradeAdmin: msg.sender)
s.trustedSmartContract = trustedSmartContract
}
function :bridgeIn, { to: :address, amount: :uint256 }, :public do
require(
msg.sender == s.trustedSmartContract,
"Only the trusted smart contract can bridge in tokens"
)
_mint(to: to, amount: amount)
end
function :setBridgeOutPause, { newState: :bool }, :public do
require(msg.sender == s.upgradeAdmin, "Only the pause admin can pause bridge outs")
s.bridgeOutPaused = newState
nil
end
function :bridgeOut, { amount: :uint256 }, :public do
require(!s.bridgeOutPaused, "Bridge out is paused")
_burn(from: msg.sender, amount: amount)
withdrawalId = esc.currentTransactionHash
s.pendingWithdrawalAmounts[msg.sender] += amount
s.pendingUserWithdrawalIds[msg.sender].push(withdrawalId)
emit :InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId
end
function :markWithdrawalComplete, {
to: :address,
amounts: [:uint256],
withdrawalIds: [:bytes32]
}, :public do
require(
msg.sender == s.trustedSmartContract,
"Only the trusted smart contract can mark withdrawals as complete"
)
for i in 0...withdrawalIds.length
withdrawalId = withdrawalIds[i]
amount = amounts[i]
require(
s.pendingWithdrawalAmounts[to] >= amount,
"Insufficient pending withdrawal"
)
require(
_removeFirstOccurenceOfValueFromArray(
s.pendingUserWithdrawalIds[to],
withdrawalId
),
"Withdrawal id not found"
)
s.pendingWithdrawalAmounts[to] -= amount
end
emit :WithdrawalComplete, to: to, amounts: amounts, withdrawalIds: withdrawalIds
end
function :getPendingWithdrawalsForUser, { user: :address }, :public, :view, returns: [:bytes32] do
return s.pendingUserWithdrawalIds[user]
end
function :_removeFirstOccurenceOfValueFromArray, { arr: array(:bytes32), value: :bytes32 }, :internal, returns: :bool do
for i in 0...arr.length
if arr[i] == value
return _removeItemAtIndex(arr: arr, indexToRemove: i)
end
end
return false
end
function :_removeItemAtIndex, { arr: array(:bytes32), indexToRemove: :uint256 }, :internal, returns: :bool do
lastIndex = arr.length - 1
if lastIndex != indexToRemove
lastItem = arr[lastIndex]
arr[indexToRemove] = lastItem
end
arr.pop
return true
end
end