Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bridgecontract
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
movabridge
bridgecontract
Commits
5d7762d3
Commit
5d7762d3
authored
Nov 14, 2025
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update scripts
parent
274eaef2
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
266 additions
and
47 deletions
+266
-47
.env.template
.env.template
+11
-0
hardhat.config.js
hardhat.config.js
+25
-47
addtokens.js
scripts/addtokens.js
+109
-0
deploy-bridge.js
scripts/deploy-bridge.js
+99
-0
tokenpairs-template.json
tokenpairs-template.json
+22
-0
No files found.
.env.template
0 → 100644
View file @
5d7762d3
# private key for deployer
DEPLOY_PRIVATE_KEY=0x
# validator addresses for bridge contract, comma separated
BRIDGE_VALIDATORS="0x,0x,0x"
# address for treasury, all assets will transfer to this address from contract.
TREASURY=0x
# address for fee receiver, all fees will be sent to this address.
FEE_RECEIVER=0x
# threshold number of validators required for multisig actions.
VALIDATOR_THRESHOLD=2
\ No newline at end of file
hardhat.config.js
View file @
5d7762d3
...
...
@@ -17,8 +17,7 @@ task("accounts", "List of accounts", async (taskArgs, hre) => {
})
const
privateKeys
=
[
process
.
env
.
DEPLOY_PRIVATE_KEY
,
// process.env.TREASURY_PRIVATE_KEY
process
.
env
.
DEPLOY_PRIVATE_KEY
];
module
.
exports
=
{
...
...
@@ -39,51 +38,32 @@ module.exports = {
settings
:
{
optimizer
:
{
enabled
:
true
,
runs
:
200
,
}
,
}
,
}
,
]
,
runs
:
200
}
}
}
]
},
etherscan
:
{
apiKey
:
{
'
achain
'
:
'
empty
'
,
'
movadev
'
:
'
empty
'
,
'
hole
'
:
'
empty
'
,
'
mova
'
:
'
empty
'
,
'
bsc
'
:
'
AVZIFYCHUFHPG9FDKNMHEWJ1VAW1H5U66T
'
'
mars
'
:
'
empty
'
,
'
mova
'
:
'
empty
'
},
customChains
:
[
{
network
:
"
achain
"
,
chainId
:
100
,
urls
:
{
apiURL
:
"
https://scan.cmp20.bitheart.org/api
"
,
browserURL
:
"
https://scan.cmp20.bitheart.org
"
}
},
{
network
:
"
hole
"
,
chainId
:
6174
,
urls
:
{
apiURL
:
"
https://holescan.bitheart.org/api
"
,
browserURL
:
"
https://holescan.bitheart.org
"
}
},
{
network
:
"
movadev
"
,
chainId
:
8891
,
network
:
"
mars
"
,
chainId
:
10323
,
urls
:
{
apiURL
:
"
https://scan.m
ova.bitheart.org
/api
"
,
browserURL
:
"
https://scan.m
ova.bitheart.org
"
apiURL
:
"
https://scan.m
ars.movachain.com
/api
"
,
browserURL
:
"
https://scan.m
ars.movachain.com
"
}
},
{
network
:
"
mova
"
,
chainId
:
10323
,
chainId
:
61900
,
urls
:
{
apiURL
:
"
https://scan.m
ars.m
ovachain.com/api
"
,
browserURL
:
"
https://scan.m
ars.m
ovachain.com
"
apiURL
:
"
https://scan.movachain.com/api
"
,
browserURL
:
"
https://scan.movachain.com
"
}
}
]
...
...
@@ -91,29 +71,27 @@ module.exports = {
networks
:
{
hardhat
:
{
accounts
:
[
{
privateKey
:
privateKeys
[
0
],
balance
:
"
10000000000000000000000
"
},
// { privateKey: privateKeys[1], balance: "10000000000000000000000" }
{
privateKey
:
privateKeys
[
0
],
balance
:
"
10000000000000000000000
"
}
]
},
achain
:
{
url
:
"
http
://15.206.56.79:28545
"
,
mars
:
{
url
:
"
http
s://mars.rpc.movachain.com
"
,
accounts
:
privateKeys
},
mova
:
{
url
:
"
https://
mars.
rpc.movachain.com
"
,
url
:
"
https://rpc.movachain.com
"
,
accounts
:
privateKeys
},
movadev
:
{
url
:
"
https://
rpc.mova.bitheart
.org
"
,
bsctest
:
{
url
:
"
https://
bsc-testnet-dataseed.bnbchain
.org
"
,
accounts
:
privateKeys
},
hole
:
{
url
:
"
https://
rpc.hole.bitheart
.org
"
,
bsc
:
{
url
:
"
https://
bsc-dataseed.bnbchain
.org
"
,
accounts
:
privateKeys
},
bsctest
:
{
// url: "https://bsctest.bitheart.org",
url
:
"
https://bsc-testnet.bnbchain.org
"
,
hole
:
{
url
:
"
https://rpc.hole.bitheart.org
"
,
accounts
:
privateKeys
}
}
...
...
scripts/addtokens.js
0 → 100644
View file @
5d7762d3
const
fs
=
require
(
"
fs
"
);
const
path
=
require
(
"
path
"
);
const
hre
=
require
(
"
hardhat
"
);
const
DEPLOY_FILE
=
path
.
join
(
__dirname
,
"
deploy.json
"
);
async
function
mintToken
(
tokenA
,
tokenB
,
user
)
{
var
amount
=
hre
.
ethers
.
parseEther
(
"
1000000
"
)
var
tx
=
await
tokenA
.
mint
(
user
,
amount
);
await
tx
.
wait
();
console
.
log
(
"
Minted TTA to user:
"
,
user
,
"
amount:
"
,
hre
.
ethers
.
formatEther
(
amount
));
tx
=
await
tokenB
.
mint
(
user
,
amount
);
await
tx
.
wait
();
console
.
log
(
"
Minted TTB to user:
"
,
user
,
"
amount:
"
,
hre
.
ethers
.
formatEther
(
amount
));
}
async
function
treasuryApprove
(
tokenA
,
tokenB
,
bridgeAddr
,
treasury
)
{
var
tx
=
await
tokenA
.
connect
(
treasury
).
approve
(
bridgeAddr
,
hre
.
ethers
.
MaxUint256
);
await
tx
.
wait
();
console
.
log
(
"
Approved TTA for bridge:
"
,
bridgeAddr
);
tx
=
await
tokenB
.
connect
(
treasury
).
approve
(
bridgeAddr
,
hre
.
ethers
.
MaxUint256
);
await
tx
.
wait
();
console
.
log
(
"
Approved TTB for bridge:
"
,
bridgeAddr
);
}
async
function
getTargetChain
(
chainId
)
{
if
(
!
fs
.
existsSync
(
DEPLOY_FILE
))
{
throw
new
Error
(
"
deploy.json file not found
"
);
}
const
deployData
=
JSON
.
parse
(
fs
.
readFileSync
(
DEPLOY_FILE
,
"
utf8
"
));
if
(
!
deployData
[
chainId
])
{
throw
new
Error
(
`No deployment data found for chainId
${
chainId
}
`
);
}
// iterator deployData to find the key not equal to chainId, chainId is number, and the key is string,
// we need convert targetChainId from string to number before return.
for
(
const
key
in
deployData
)
{
if
(
key
!=
chainId
.
toString
())
{
return
Number
(
key
);
}
}
throw
new
Error
(
`No target chain found for chainId
${
chainId
}
`
);
}
async
function
getDeploy
(
chainId
)
{
if
(
!
fs
.
existsSync
(
DEPLOY_FILE
))
{
throw
new
Error
(
"
deploy.json file not found
"
);
}
const
deployData
=
JSON
.
parse
(
fs
.
readFileSync
(
DEPLOY_FILE
,
"
utf8
"
));
if
(
!
deployData
[
chainId
])
{
throw
new
Error
(
`No deployment data found for chainId
${
chainId
}
`
);
}
const
addrs
=
deployData
[
chainId
];
const
bridge
=
await
hre
.
ethers
.
getContractAt
(
"
Bridge
"
,
addrs
.
bridge
);
return
{
bridge
}
}
async
function
setOutConfig
(
curTokenMap
,
targetTokenMap
,
targetChainId
,
bridge
)
{
const
outConfigA
=
{
receiveToken
:
await
targetTokenMap
.
tokenA
.
getAddress
(),
fee
:
hre
.
ethers
.
parseEther
(
"
0.05
"
),
limit
:
hre
.
ethers
.
parseEther
(
"
1000
"
),
isBurn
:
false
,
enabled
:
true
,
};
const
outConfigB
=
{
receiveToken
:
await
targetTokenMap
.
tokenB
.
getAddress
(),
fee
:
hre
.
ethers
.
parseEther
(
"
0.04
"
),
limit
:
hre
.
ethers
.
parseEther
(
"
1000
"
),
isBurn
:
false
,
enabled
:
true
,
}
var
tx
=
await
bridge
.
changeOutConfig
(
await
curTokenMap
.
tokenA
.
getAddress
(),
targetChainId
,
// Target chain ID
outConfigA
);
await
tx
.
wait
();
console
.
log
(
"
Set out config for tokenA to chain
"
,
targetChainId
,
"
tx
"
,
tx
.
hash
);
tx
=
await
bridge
.
changeOutConfig
(
await
curTokenMap
.
tokenB
.
getAddress
(),
targetChainId
,
// Target chain ID
outConfigB
);
await
tx
.
wait
();
console
.
log
(
"
Set out config for tokenB to chain
"
,
targetChainId
,
"
tx
"
,
tx
.
hash
);
}
// Define the script
async
function
main
()
{
const
chainId
=
await
hre
.
ethers
.
provider
.
getNetwork
().
then
(
network
=>
network
.
chainId
);
const
curChainDeploy
=
await
getDeploy
(
chainId
);
await
setConfig
(
curChainDeploy
.
bridge
);
console
.
log
(
"
Configuration set successfully for chain
"
,
chainId
);
}
// Run the script
main
().
catch
((
error
)
=>
{
console
.
error
(
"
Error:
"
,
error
);
});
\ No newline at end of file
scripts/deploy.js
→
scripts/deploy
-bridge
.js
View file @
5d7762d3
...
...
@@ -4,18 +4,12 @@ const { ethers, upgrades } = require("hardhat");
const
DEPLOY_FILE
=
path
.
join
(
__dirname
,
"
deploy.json
"
);
async
function
deploy
()
{
const
token
=
await
ethers
.
getContractFactory
(
"
TestToken
"
);
const
tokenA
=
await
token
.
deploy
(
"
Test Token Ali
"
,
"
TTA
"
);
await
tokenA
.
waitForDeployment
();
const
tokenAAddr
=
await
tokenA
.
getAddress
();
const
tokenB
=
await
token
.
deploy
(
"
Test Token Bob
"
,
"
TTB
"
);
await
tokenB
.
waitForDeployment
();
const
tokenBAddr
=
await
tokenB
.
getAddress
();
let
INITIAL_VALIDATORS
=
process
.
env
.
BRIDGE_VALIDATORS
let
TREASURY
=
process
.
env
.
TREASURY
let
FEE_RECEIVER
=
process
.
env
.
FEE_RECEIVER
let
VALIDATOR_THRESHOLD
=
process
.
env
.
VALIDATOR_THRESHOLD
async
function
deploy
()
{
// Deploy the contract
const
factory
=
await
ethers
.
getContractFactory
(
"
Bridge
"
...
...
@@ -29,21 +23,65 @@ async function deploy() {
const
bridgeAddr
=
await
contract
.
getAddress
();
const
chainId
=
await
ethers
.
provider
.
getNetwork
().
then
(
network
=>
network
.
chainId
);
await
saveDeployment
(
chainId
,
tokenAAddr
,
tokenBAddr
,
bridgeAddr
);
console
.
log
(
"
initial_height =
"
,
contract
.
deploymentTransaction
().
blockNumber
)
console
.
log
(
"
bridge_contract =
"
,
bridgeAddr
)
const
initialHeight
=
contract
.
deploymentTransaction
().
blockNumber
;
await
saveDeployment
(
chainId
,
bridgeAddr
,
initialHeight
);
await
setConfig
(
contract
);
console
.
log
(
"
deploy bridge contract
"
,
bridgeAddr
,
"
at block
"
,
initialHeight
);
}
async
function
addValidators
(
contract
,
validators
)
{
let
validatorList
=
validators
.
split
(
'
,
'
)
for
(
let
i
=
0
;
i
<
validatorList
.
length
;
i
++
)
{
var
tx
=
await
contract
.
addValidator
(
validatorList
[
i
])
await
tx
.
wait
();
console
.
log
(
"
added validator:
"
,
validatorList
[
i
]);
}
}
async
function
setValidatorRequired
(
contract
,
count
)
{
var
tx
=
await
contract
.
changeValidRequired
(
count
);
await
tx
.
wait
();
console
.
log
(
"
set validate threshold to:
"
,
count
);
}
function
saveDeployment
(
chainId
,
tokenA
,
tokenB
,
bridge
)
{
async
function
setTreasury
(
contract
,
treasury
)
{
var
tx
=
await
contract
.
setTreasury
(
treasury
);
await
tx
.
wait
();
console
.
log
(
"
set treasury to:
"
,
treasury
);
}
async
function
setFeeReceiver
(
contract
,
receiver
)
{
var
tx
=
await
contract
.
setFeeReceiver
(
receiver
);
await
tx
.
wait
();
console
.
log
(
"
set fee receiver to:
"
,
receiver
);
}
async
function
setConfig
(
bridge
)
{
if
(
!
INITIAL_VALIDATORS
||
!
TREASURY
)
{
throw
new
Error
(
"
Environment variables BRIDGE_VALIDATORS or TREASURY are not set.
"
);
}
await
addValidators
(
bridge
,
INITIAL_VALIDATORS
);
await
setValidatorRequired
(
bridge
,
VALIDATOR_THRESHOLD
);
await
setFeeReceiver
(
bridge
,
FEE_RECEIVER
);
// if TREASURY not empty, set treasury.
if
(
TREASURY
)
{
await
setTreasury
(
bridge
,
TREASURY
);
}
}
function
saveDeployment
(
chainId
,
bridge
,
initialHeight
)
{
let
deployData
=
{};
if
(
fs
.
existsSync
(
DEPLOY_FILE
))
{
deployData
=
JSON
.
parse
(
fs
.
readFileSync
(
DEPLOY_FILE
,
"
utf8
"
));
}
deployData
[
chainId
]
=
{
tokenA
,
tokenB
,
bridge
,
initialHeight
,
};
fs
.
writeFileSync
(
DEPLOY_FILE
,
JSON
.
stringify
(
deployData
,
null
,
2
));
...
...
tokenpairs-template.json
0 → 100644
View file @
5d7762d3
{
"6174"
:
[
{
"token"
:
"0xYourTokenAddressHere"
,
"fee"
:
"1000000000000000000"
,
"limit"
:
1000
,
"isBurn"
:
false
,
"targetChain"
:
"10323"
,
"targetToken"
:
"0xTargetTokenAddressHere"
}
],
"10323"
:
[
{
"token"
:
"0xYourTokenAddressHere"
,
"fee"
:
"1000000000000000000"
,
"limit"
:
1000
,
"isBurn"
:
false
,
"targetChain"
:
"6174"
,
"targetToken"
:
"0xTargetTokenAddressHere"
}
]
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment