Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xWELL #81

Merged
merged 213 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
213 commits
Select commit Hold shift + click to select a range
2ff2b8c
checkpoint
ElliotFriedman Nov 15, 2023
b414522
check out to proper branches
ElliotFriedman Nov 15, 2023
42760e6
compiling
ElliotFriedman Nov 15, 2023
c8a0f48
pause contracts
ElliotFriedman Nov 16, 2023
4127101
initializer and make struct visible to external files
ElliotFriedman Nov 16, 2023
580f5f8
add lockbox
ElliotFriedman Nov 16, 2023
f3dcad2
remove custom errors, format interface
ElliotFriedman Nov 16, 2023
2f5556a
initializer, spend allowance on burn, totalSupply lte 5b invariant in…
ElliotFriedman Nov 16, 2023
a8f4200
remove errors and native functionality
ElliotFriedman Nov 16, 2023
e524d2b
format
ElliotFriedman Nov 16, 2023
b1b822c
xwell deploy helpers
ElliotFriedman Nov 16, 2023
d71a15a
natspec
ElliotFriedman Nov 16, 2023
779ddb4
xwell and lockbox setup
ElliotFriedman Nov 16, 2023
3eaf4ba
xWELL unit test
ElliotFriedman Nov 16, 2023
2eec634
remove MintLimits import
ElliotFriedman Nov 16, 2023
a3ace59
rateLimitPerSecond public getter
ElliotFriedman Nov 16, 2023
6a76aa3
remove todo, add check that token cannot be transferred to token cont…
ElliotFriedman Nov 16, 2023
55e8e62
lock box invariants
ElliotFriedman Nov 16, 2023
8601451
remove init function
ElliotFriedman Nov 17, 2023
2ea5af7
remove init function
ElliotFriedman Nov 17, 2023
e4286b8
natspec, refactor init to bulk add internal helper functions, add rem…
ElliotFriedman Nov 17, 2023
9a842dd
add and remove bridges functionality, natspec, remove init function c…
ElliotFriedman Nov 17, 2023
503e207
RateLimitMidPointInfo import style change
ElliotFriedman Nov 17, 2023
2302b64
RateLimitMidPointInfo import style change
ElliotFriedman Nov 17, 2023
8e6315c
add additional tests and todo of unit tests to add
ElliotFriedman Nov 17, 2023
b1e5361
xwell pausing tests
ElliotFriedman Nov 17, 2023
0113645
add additional tests
ElliotFriedman Nov 17, 2023
387e876
remove endPause helper function
ElliotFriedman Nov 17, 2023
59ce117
add _resetPauseState to remove duplicate code
ElliotFriedman Nov 17, 2023
ca1029b
10k per second max rate limit per second
ElliotFriedman Nov 17, 2023
39b019b
add max pause duration
ElliotFriedman Nov 17, 2023
d6ca20c
make setup virtual
ElliotFriedman Nov 17, 2023
16dfc53
start of docs
ElliotFriedman Nov 17, 2023
4edd509
token function pause description
ElliotFriedman Nov 17, 2023
5661ff1
natspec, event cleanup
ElliotFriedman Nov 18, 2023
4f92f6c
remove pauseUsed state variable, simplify contract further
ElliotFriedman Nov 18, 2023
dbfa8c9
remove _startPause function
ElliotFriedman Nov 18, 2023
d92633c
remove MAX_RATE_LIMIT_PER_SECOND, add maxRateLimitPerSecond
ElliotFriedman Nov 18, 2023
0dd94fe
revert message fix, remove setLimits test
ElliotFriedman Nov 18, 2023
76c84a7
add abstract ERC20 contract
ElliotFriedman Nov 18, 2023
924da0d
remove functions in xERC20, and override helper methods
ElliotFriedman Nov 18, 2023
93a1738
update interface to remove setLimit and other unused values
ElliotFriedman Nov 18, 2023
ba9e572
add min buffer cap to mint limits
ElliotFriedman Nov 18, 2023
31f46d0
add MIN_BUFFER_CAP and override getter function
ElliotFriedman Nov 18, 2023
7d75164
fix MIN_BUFFER_CAP in tests
ElliotFriedman Nov 18, 2023
b21474a
cover min buffer cap failing test cases
ElliotFriedman Nov 18, 2023
b090388
add tests to cover non-existent bridge removal failure
ElliotFriedman Nov 18, 2023
bea4098
bridge existence check on limit removal
ElliotFriedman Nov 18, 2023
b1290c3
fix test
ElliotFriedman Nov 18, 2023
584ece7
fix test
ElliotFriedman Nov 18, 2023
c2bd891
Axelar Bridge Adapter
ElliotFriedman Nov 18, 2023
b34925b
xERC20 bridge adapter
ElliotFriedman Nov 18, 2023
ba99d65
axelar interfaces and library
ElliotFriedman Nov 18, 2023
b4b9e2f
change IWormhole import path
ElliotFriedman Nov 21, 2023
eb43b2a
wormhole trusted sender
ElliotFriedman Nov 21, 2023
b5288a1
wormhole trusted sender implementation
ElliotFriedman Nov 21, 2023
c958805
new wormhole folder
ElliotFriedman Nov 21, 2023
95e7328
wormhole bridge adapter
ElliotFriedman Nov 21, 2023
65c8507
wormhole mock relayer
ElliotFriedman Nov 21, 2023
f87f317
wormhole bridge adapter unit test
ElliotFriedman Nov 21, 2023
f523490
move IWormhole
ElliotFriedman Nov 21, 2023
0f9905d
fix temporal governor import
ElliotFriedman Nov 21, 2023
2469613
fix IWormhole import
ElliotFriedman Nov 21, 2023
ca8b338
add WORMHOLE_RELAYER on moonbeam and base
ElliotFriedman Nov 21, 2023
3e556c5
remove pause specific tests todo
ElliotFriedman Nov 21, 2023
6e1b04c
fix compiler warnings around pure and view
ElliotFriedman Nov 21, 2023
bd712fd
natspec, admin functions, polishing
ElliotFriedman Nov 21, 2023
412ac78
remove error retry
ElliotFriedman Nov 21, 2023
f586795
split deployment and initialization into two separate steps
ElliotFriedman Nov 21, 2023
bb5f783
refactor base test to use new deployment and initialization functions
ElliotFriedman Nov 21, 2023
a118f18
fix compiler warnings on unused variables
ElliotFriedman Nov 21, 2023
55693db
IWormhole import path update
ElliotFriedman Nov 21, 2023
c28b4f1
IWormhole import path update
ElliotFriedman Nov 21, 2023
6bd4932
remove unused local variable
ElliotFriedman Nov 21, 2023
04eff64
add additional test around rate limit for wormhole bridge adapter
ElliotFriedman Nov 22, 2023
29e0665
remove wormholeBridgeAdapterProxy as bridge in xWELL fuzz test
ElliotFriedman Nov 22, 2023
88791e1
remove comments
ElliotFriedman Nov 22, 2023
243ce9b
make bridgeCost external
ElliotFriedman Nov 22, 2023
3888ca5
natspec, clean up comments
ElliotFriedman Nov 22, 2023
6b23ee6
add more tests for removing and adding failure cases
ElliotFriedman Nov 22, 2023
6196251
remove bridgeCost(uint256,uint256,address) interface from xerc20 brid…
ElliotFriedman Nov 22, 2023
35f56f9
deployment script refactor for both base and moonbeam
ElliotFriedman Nov 22, 2023
0856fff
remove todo comment
ElliotFriedman Nov 22, 2023
45f7b23
audit feedback: remove safecast
ElliotFriedman Nov 27, 2023
326357f
audit feedback: add __ERC20Permit_init(tokenName) into xwell
ElliotFriedman Nov 27, 2023
960ad46
test eip712 properly initialized
ElliotFriedman Nov 27, 2023
0d6a51e
remove unused variable
ElliotFriedman Nov 27, 2023
2755d95
add comments around kicking guardian
ElliotFriedman Nov 27, 2023
4c13ddc
add: testKickGuardianSucceedsAfterUnpause
ElliotFriedman Nov 27, 2023
eafedee
comment: states for pause guardian
ElliotFriedman Nov 27, 2023
4460bdd
mock timestamp governor, conforms to new erc20 getPastVotes interface
ElliotFriedman Nov 28, 2023
f338da3
unit test: xWELL token voting
ElliotFriedman Nov 28, 2023
930c01d
add lock and burn helper functions into BaseTest
ElliotFriedman Nov 28, 2023
0e90b58
update comment, remove TODO
ElliotFriedman Nov 28, 2023
86c7b13
move helper functions out of unit test file
ElliotFriedman Nov 28, 2023
8a62584
update comments
ElliotFriedman Nov 28, 2023
cc88507
add midpoint getter function to MintLimits
ElliotFriedman Dec 2, 2023
3ab5379
testDelegateReceivesAdditionalVotesAfterMint
ElliotFriedman Dec 2, 2023
ab03386
initial cut of formal specifications
ElliotFriedman Dec 2, 2023
0cab953
certora spec
ElliotFriedman Dec 2, 2023
465ba97
add .certora_internal/ to gitignore
ElliotFriedman Dec 2, 2023
54ba3d9
fix totalSupplyLteUint224Max, add todo's around ghost
ElliotFriedman Dec 4, 2023
6691cb0
add getPastTotalSupply function
ElliotFriedman Dec 4, 2023
fbd607f
add total supply hooks and userCanDelegateBalance rule
ElliotFriedman Dec 4, 2023
a551345
total supply checkpoints bit masking
ElliotFriedman Dec 4, 2023
393b43e
preserve supply and in sync invariants
ElliotFriedman Dec 4, 2023
921b3f6
immediately transfer ownership in initializer to ensure deployer does…
ElliotFriedman Dec 5, 2023
bbd6037
xWELL Base Deploy Script
ElliotFriedman Dec 5, 2023
ebcd5d0
additional unit tests to get coverage higher
ElliotFriedman Dec 5, 2023
65b32d3
add moonbeam guardian
ElliotFriedman Dec 6, 2023
183c43c
refactor addAddress function to remove footguns
ElliotFriedman Dec 6, 2023
ac362d8
mip-b12 deployment scripts for both base and moonbeam
ElliotFriedman Dec 6, 2023
3293867
fix failing tests
ElliotFriedman Dec 6, 2023
6f50176
factor code out
ElliotFriedman Dec 6, 2023
2da30bc
remove xwell deploy script
ElliotFriedman Dec 6, 2023
9961773
update helper to properly handle new xWELLDeploy contract that accept…
ElliotFriedman Dec 6, 2023
9171fdf
proxy admin upgrades contracts
ElliotFriedman Dec 6, 2023
7468a57
invariant test docs
ElliotFriedman Dec 7, 2023
0a5429d
xWELL invariant tests
ElliotFriedman Dec 7, 2023
4c15b8f
remove comments
ElliotFriedman Dec 7, 2023
a6636b2
add additional assertion around wormhole relayer, remove unused varia…
ElliotFriedman Dec 7, 2023
a4998c1
naming, add getter function for invariant tests
ElliotFriedman Dec 7, 2023
2decda3
debugging on duplicate item
ElliotFriedman Dec 7, 2023
4d5c066
remove check on mainnet
ElliotFriedman Dec 7, 2023
0e4145e
exclude mip-b12
ElliotFriedman Dec 7, 2023
b8cf0ea
mint limits changes reverted
ElliotFriedman Dec 7, 2023
196bf38
add additional invariant tests, unbound max rate limit per second set…
ElliotFriedman Dec 7, 2023
4791257
remove console.log in test
ElliotFriedman Dec 7, 2023
897d73b
fix failing tests
ElliotFriedman Dec 7, 2023
10e08a1
fix failing integration tests
ElliotFriedman Dec 7, 2023
8fa4cda
Merge pull request #95 from moonwell-fi/feat/invariant
ElliotFriedman Dec 7, 2023
b114e1d
natspec
ElliotFriedman Dec 7, 2023
a2e92da
natspec
ElliotFriedman Dec 7, 2023
d11f7d3
frontend integration instructions
ElliotFriedman Dec 8, 2023
7fe8dd9
add base <-> moonbeam mappings
ElliotFriedman Dec 8, 2023
c6c1e98
fix wormhole relayer address for base
ElliotFriedman Dec 8, 2023
cdb02aa
xwell changes
ElliotFriedman Dec 8, 2023
a176d2d
xWELL integration tests
ElliotFriedman Dec 8, 2023
36989a3
integration test instructions
ElliotFriedman Dec 8, 2023
5b8086d
fix chainids, add additional assertion
ElliotFriedman Dec 8, 2023
27477ab
ERC20 spec passing
ElliotFriedman Dec 9, 2023
6b0ea51
remove unused ghost
ElliotFriedman Dec 9, 2023
417fcc6
corretCheckpoints -> correctCheckpoints
ElliotFriedman Dec 9, 2023
fdabf23
allowance increase/decrease rules
ElliotFriedman Dec 11, 2023
1c9c89b
remove mintLimits midpoint function
ElliotFriedman Dec 11, 2023
8e828d2
remove unneeded invariants for rule burn
ElliotFriedman Dec 11, 2023
7fc5aa9
remove unneeded function for rule burn
ElliotFriedman Dec 11, 2023
da77682
pauseable interface
ElliotFriedman Dec 12, 2023
7ad875e
pause specification
ElliotFriedman Dec 12, 2023
c63a2d2
pause guardian config
ElliotFriedman Dec 12, 2023
15d7a37
constrain burn rule
ElliotFriedman Dec 12, 2023
5ebc423
increment and get nonce scripts
ElliotFriedman Dec 12, 2023
0fac272
burn specification
ElliotFriedman Dec 12, 2023
30b7bff
Merge pull request #96 from moonwell-fi/certora-specifications
ElliotFriedman Dec 12, 2023
a0049de
Merge pull request #88 from moonwell-fi/feat/wormhole-bridge-adapter
ElliotFriedman Dec 12, 2023
6da728a
fix merge conflicts
ElliotFriedman Dec 12, 2023
b65f8c2
IWormhole import
ElliotFriedman Dec 12, 2023
ee63485
@openzeppelin/ remappings
ElliotFriedman Dec 12, 2023
63bc1a1
use MOONBEAM_PROXY_ADMIN to ensure proper addresses on cross chain xWELL
ElliotFriedman Dec 12, 2023
6474976
script updates to sync nonces
ElliotFriedman Dec 12, 2023
c994b22
correct wormhole chainids in deployment scripts
ElliotFriedman Dec 12, 2023
96e2fe9
integration tests validating deployed system
ElliotFriedman Dec 12, 2023
e4960dd
add xWELL and wormhole bridge adapter addresses on both chains + xERC…
ElliotFriedman Dec 12, 2023
32dc53c
reinitialize failure
ElliotFriedman Dec 12, 2023
40eb9ac
xWELL add docs on router and events
ElliotFriedman Dec 14, 2023
5e0757c
xWELL Router
ElliotFriedman Dec 14, 2023
3e0d1e4
xwell router tests
ElliotFriedman Dec 14, 2023
48bd4fe
add event on bridge out success
ElliotFriedman Dec 14, 2023
febd86f
increase test coverage
ElliotFriedman Dec 14, 2023
92c7e35
fix issue around chainid always returning true due to abi.encode
ElliotFriedman Dec 15, 2023
42bbe95
remove TODO
ElliotFriedman Dec 15, 2023
97ee557
add axelar bridge deployment
ElliotFriedman Dec 15, 2023
1825994
remove newline
ElliotFriedman Dec 15, 2023
4b1eef4
axelar mock contract
ElliotFriedman Dec 15, 2023
a8d6e3f
axelar bridge adapter unit tests
ElliotFriedman Dec 15, 2023
ac1da23
lcov added to gitignore
ElliotFriedman Dec 15, 2023
6276b5f
make run view
ElliotFriedman Dec 15, 2023
8853dba
xwell router deploy script
ElliotFriedman Dec 15, 2023
168b3b6
xWELL token max rate limit per second set to 1k
ElliotFriedman Dec 19, 2023
81d5c23
update contract names for tests
ElliotFriedman Dec 19, 2023
4a1b963
add invariant to ci run
ElliotFriedman Dec 19, 2023
447acae
moonbeam integration tests
ElliotFriedman Dec 19, 2023
40d5a0f
additional specifications around mint limits
ElliotFriedman Dec 19, 2023
839fb27
pause guardian grant documentation
ElliotFriedman Dec 19, 2023
8c93140
fix failing test due to decreased max rate limit per second
ElliotFriedman Dec 19, 2023
21ee9fd
update tests to follow convention to be included in CI runs
ElliotFriedman Dec 19, 2023
44125b9
update name to WELL from xWELL
ElliotFriedman Dec 19, 2023
0e1b35a
add names to mapping key and value
ElliotFriedman Dec 19, 2023
69cd0f9
update name to WELL from xWELL
ElliotFriedman Dec 19, 2023
ba67b4a
add MOONBEAM_API_KEY to env
ElliotFriedman Dec 19, 2023
427f8b5
'WELL Token' -> 'WELL'
ElliotFriedman Dec 19, 2023
67fb162
additional unit tests'
ElliotFriedman Dec 19, 2023
74538b4
MAX_RATE_LIMIT_PER_SECOND 25k/s, can only grant guardian while unpaus…
ElliotFriedman Dec 19, 2023
b544326
docs owner pausing update
ElliotFriedman Dec 19, 2023
fa852dc
additional tests for ownerUnpause and whenPaused grantGuardian as owner
ElliotFriedman Dec 19, 2023
416327e
Merge pull request #98 from moonwell-fi/feat-xwell-cleanup
ElliotFriedman Dec 20, 2023
d1a69cb
Merge pull request #97 from moonwell-fi/feat/x-well-router
ElliotFriedman Dec 28, 2023
e7259eb
new xWELL deploy
ElliotFriedman Jan 8, 2024
0a72a8f
fix logging of address
ElliotFriedman Jan 8, 2024
49eedc5
bytes32 pk import and log deployer address
ElliotFriedman Jan 8, 2024
fe3ca0c
fix merge conflicts
ElliotFriedman Jan 8, 2024
23edc67
add xwell router
ElliotFriedman Jan 9, 2024
5081b03
xwell router deploy script fixes, broadcast and pk import
ElliotFriedman Jan 9, 2024
e31614f
add additional assertion
ElliotFriedman Jan 9, 2024
e2dbd74
remove function call in test to non-existent function
ElliotFriedman Jan 9, 2024
32d39b9
rename folder and files
ElliotFriedman Jan 9, 2024
38123f7
remove old files
ElliotFriedman Jan 9, 2024
eae9a13
fix import to new file
ElliotFriedman Jan 9, 2024
04f5c86
test xWELL permit
anajuliabit Jan 22, 2024
80c74b8
double quotes
anajuliabit Jan 22, 2024
b42aeee
bracket spacing
anajuliabit Jan 22, 2024
b93e94e
Merge pull request #104 from moonwell-fi/test/xwell-permit
ElliotFriedman Jan 22, 2024
11cdc33
fix merge conflicts
ElliotFriedman Jan 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/helper/get-env-var.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ LATEST_MIP_DIR=$(ls -1v ${BASE_DIR}/ | grep '^mip-b' | tail -n 1)

MIP_NUM=${LATEST_MIP_DIR:5:2}

if [[ "$LATEST_MIP_DIR" == "mip-b07.sol" ]]; then
if [[ "$LATEST_MIP_DIR" == "mip-b12-moonbeam.sol" ]]; then
echo "PROPOSAL_ARTIFACT_PATH="
else
echo "PROPOSAL_ARTIFACT_PATH=${BASE_DIR}/${LATEST_MIP_DIR}/mipb${MIP_NUM}.json"
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/invariant.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Foundry invariant tests

on: [pull_request]

jobs:
invariant-tests:
name: invariant-tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup Environment
uses: ./.github/actions

- name: Invariant Test Contracts
run: time forge test -vvv --match-contract InvariantTest
1 change: 0 additions & 1 deletion .github/workflows/moonbeam-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on: [pull_request]

env:
MOONBEAM_API_KEY: ${{secrets.MOONBEAM_API_KEY}}
ETHERSCAN_API_KEY: ${{secrets.ETHERSCAN_API_KEY}}

jobs:
run-moonbeam-tests:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,7 @@ typescript/node_modules/
typescript/package-lock.json

typescript/yarn.lock

.certora_internal/

lcov.info
7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/transmissions11/solmate
[submodule "lib/zelt"]
path = lib/zelt
url = https://github.com/solidity-labs-io/zelt
branch = main
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
23 changes: 23 additions & 0 deletions certora/confs/ConfigurablePauseGuardian.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"files": [
"src/xWELL/xWELL.sol"
],
"verify": "xWELL:certora/specs/Pause.spec",
"send_only": true,
"optimistic_loop": true,
"solc": "solc",
"msg": "Verification of Configurable Pause Guardian",
"rule_sanity": "basic",
"packages": [
"@forge-std/=lib/forge-std/src/",
"@openzeppelin-contracts/=lib/openzeppelin-contracts/",
"@openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"@protocol=src/",
"@test=test/",
"@proposals=src/proposals/",
"@utils/=utils/",
"@zelt/=lib/zelt/",
"@zelt-src/=lib/zelt/src/",
"@zelt-test/=lib/zelt/test/"
]
}
23 changes: 23 additions & 0 deletions certora/confs/ERC20.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"files": [
"src/xWELL/xWELL.sol"
],
"verify": "xWELL:certora/specs/ERC20.spec",
"send_only": true,
"optimistic_loop": true,
"solc": "solc",
"msg": "Verification of xWELL Token",
"rule_sanity": "basic",
"packages": [
"@forge-std/=lib/forge-std/src/",
"@openzeppelin-contracts/=lib/openzeppelin-contracts/",
"@openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"@protocol=src/",
"@test=test/",
"@proposals=src/proposals/",
"@utils/=utils/",
"@zelt/=lib/zelt/",
"@zelt-src/=lib/zelt/src/",
"@zelt-test/=lib/zelt/test/"
]
}
656 changes: 656 additions & 0 deletions certora/specs/ERC20.spec

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions certora/specs/IERC20.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
methods {
function name() external returns (string) envfree;
function symbol() external returns (string) envfree;
function decimals() external returns (uint8) envfree;
function totalSupply() external returns (uint256) envfree;
function maxSupply() external returns (uint256) envfree;
function MAX_SUPPLY() external returns (uint256) envfree;
function balanceOf(address) external returns (uint256) envfree;
function allowance(address,address) external returns (uint256) envfree;
function approve(address,uint256) external returns (bool) ;
function transfer(address,uint256) external returns (bool) ;
function transferFrom(address,address,uint256) external returns (bool) ;
function paused() external returns (bool) ;
function buffer(address) external returns (uint256) ;
function getPastTotalSupply(uint256) external returns (uint256) ;
function numCheckpoints(address) external returns (uint32) envfree;
function delegates(address) external returns (address) envfree;
function bufferCap(address) external returns (uint256) envfree;
function getVotes(address) external returns (uint256) envfree;
function rateLimitPerSecond(address) external returns (uint256) envfree;
function minBufferCap() external returns (uint112) envfree;
function maxRateLimitPerSecond() external returns (uint128) envfree;
}
5 changes: 5 additions & 0 deletions certora/specs/IERC2612.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
methods {
function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) external;
function nonces(address) external returns (uint256) envfree;
function DOMAIN_SEPARATOR() external returns (bytes32) envfree;
}
7 changes: 7 additions & 0 deletions certora/specs/IPauseable.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
methods {
function pauseStartTime() external returns (uint128) envfree;
function maxPauseDuration() external returns (uint256) envfree;
function pauseDuration() external returns (uint128) envfree;
function pauseGuardian() external returns (address) envfree;
function paused() external returns (bool) ;
}
131 changes: 131 additions & 0 deletions certora/specs/Pause.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import "helpers.spec";
import "IERC20.spec";
import "IERC2612.spec";
import "IPauseable.spec";

function timestampMax() returns uint256 {
return 2 ^ 128 - 1;
}

function uintMax() returns uint256 {
return 2 ^ 256 - 1;
}

/// Preconditions:
/// - block timestamp is under or equal uint32 max and gt 0

/// Invariants:
/// 1. paused, pauseStartTime != 0, guardian != address(0)
/// 2. unpaused, pauseStartTime == 0, guardian == address(0)
/// 3. unpaused, pauseStartTime <= block.timestamp - pauseDuration, guardian != address(0)
/// 4. unpaused after kick, pauseStartTime == 0, guardian == address(0)
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Ghost: all state variables │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
ghost address pauseGuardian {
init_state axiom pauseGuardian == 0;
}

/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Hooks: all state variables │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

/// @title The hook for writing to pause guardian
hook Sstore pauseGuardian address newPauseGuardian (address oldPauseGuardian) STORAGE
{
pauseGuardian = newPauseGuardian;
}

/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Invariants │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

invariant pauseGuardianMirrorCorrect()
pauseGuardian == pauseGuardian();

invariant pauseDurationLteMax()
assert_uint256(pauseDuration()) <= maxPauseDuration();

invariant pausedCorrect(env e)
paused(e) => (
to_mathint(e.block.timestamp) >= to_mathint(pauseStartTime()) &&
to_mathint(e.block.timestamp) <= pauseStartTime() + pauseDuration()
) {
preserved {
require timestampMax() >= e.block.timestamp;
requireInvariant pauseDurationLteMax();
requireInvariant pauseGuardianMirrorCorrect();
} preserved pause() with (env e1) {
require e1.block.timestamp == e.block.timestamp;
require timestampMax() >= e1.block.timestamp;
requireInvariant pausedCorrect(e1);
requireInvariant pauseDurationLteMax();
requireInvariant pauseGuardianMirrorCorrect();
}
}

/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Rule: kick behavior and side effects │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
rule kickSucceeds(env e) {
require pauseUsed(e);
require !paused(e);
require pauseGuardian != 0;

address guardianStartingAddress = pauseGuardian;

kickGuardian(e);

assert !paused(e), "not unpaused";
assert pauseGuardian == 0, "pause guardian address 0";
assert pauseStartTime() == 0, "pause start time not reset";
assert guardianStartingAddress != 0, "guardianStartingAddress eq 0 address";
}

/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Rule: pause/unpause behavior and side effects │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
rule pauseSucceeds(env e) {
/// constrain the prover to a sane block timestamp we will see in this lifetime
require e.block.timestamp > 0 && e.block.timestamp <= timestampMax();
require !pauseUsed(e);
require !paused(e);
require pauseGuardian != 0;

address guardianStartingAddress = pauseGuardian;

pause(e);

assert paused(e), "not paused";
assert pauseUsed(e) == true, "pause used";
assert pauseGuardian == guardianStartingAddress, "pause guardian address 0";
assert to_mathint(pauseStartTime()) == to_mathint(e.block.timestamp), "pause start time not set";
}

rule unpauseSucceeds(env e) {
/// constrain the prover to a sane block timestamp we will see in this lifetime
require e.block.timestamp > 0 && e.block.timestamp <= timestampMax();
require pauseUsed(e);
require paused(e);
require pauseGuardian != 0;

address guardianStartingAddress = pauseGuardian;

unpause(e);

assert !paused(e), "not paused";
assert !pauseUsed(e) == true, "pause should not be used";
assert pauseStartTime() == 0, "pause start time not reset";
assert pauseGuardian == 0, "pause guardian not kicked";
assert guardianStartingAddress != 0, "pause start time not reset";
}
1 change: 1 addition & 0 deletions certora/specs/helpers.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
definition nonpayable(env e) returns bool = e.msg.value == 0;
60 changes: 60 additions & 0 deletions docs/xWELL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Overview

The xWELL token is an xERC20 compatible token that is meant to be used as a cross chain fungible token. It relies on trusted bridge contracts that are given a rate limit in the MintLimits class. Each bridge has a different rate limit to prevent infinite mints when a single bridge is compromised. A lockbox contract is used on the source chain to allow migration of existing WELL holders over to the new WELL token.

## Frontend Integration

In order to allow token holders to seamlessly use the bridge, the frontend will need to understand the following flows for end users when moving between chains. To go from chain A to chain B, a user must first approve the wormhole or relevant bridge adapter contract the ability to spend their xWELL. Once approved, the user can then call the bridge adapter's `bridge(uint256 dstChainId,uint256 amount,address to)` function. The destination chain id should be the wormhole chainId of the destination chain. The amount should be the amount of xWELL the user wants to bridge. The to address should be the address of the receiving user on the destination chain. The bridge adapter will then transfer the xWELL from the user to the bridge contract, and then the bridge contract will mint the same amount of xWELL on the destination chain. The user will then be able to use the xWELL on the destination chain.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ElliotFriedman I'm curious about what other routes will use - will we always use the Wormhole destination chain ID, regardless of which route the actual bridge operation takes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're using wormhole, then yes, you will need to always provide the wormhole destination chain id.

However, if you're using the axelar adapter, then you would need to specify the proper axelar destination chain id.

A valid route must use the same provider on both chains to send and receive.


To find out the required amount of gas to be spent to ensure a transaction is successful, the frontend can call the `bridgeCost(uint16 dstChainId)` function on the bridge adapter. This function takes only the destination wormhole chain id the parameter, and returns the maximum amount of gas that should be spent to ensure the transaction is successful. The frontend can then use this value to set the amount native asset to pay for the transaction. This amount of native tokens should be sent in the call to bridge.

### Router Contract

In order to use the router to simplify users migrating from WELL to xWELL, the frontend will need to talk to the router contract. Users will approve the router to spend their WELL and then call `bridgeToBase(address to, uint256 amount)` if to is different from sender, or `bridgeToBase(uint256 amount)` if to is the same as sender. The router will then transfer the WELL from the user to the lockbox contract, and then the lockbox contract will mint the same amount of xWELL to the router, which will then migrate those tokens to xWELL the base chain through the WormholeAdapter. The user must pass the correct amount of GLMR to the router to cover the gas costs of the transaction. The amount can be found by calling the `bridgeCost()` function on the router contract which returns a uint256.

### Events

When a user uses the WormholeBridgeAdapter contract to move tokens from one chain to another, the following events will be emitted

from the xWELL token:

On Mint:
```Transfer(address(0), to, amount);```
```BufferUsed(amount, newBufferStored);```

On Burn:
```Transfer(from, address(0), amount);```
```BufferReplenished(amount, newBufferStored);```

from the WormholeBridgeAdapter:

on Mint:
```BridgedIn(chainId, user, amount)```
```BridgedIn(uint256 indexed srcChainId, address indexed tokenReceiver, uint256 amount);```

on Burn:
```TokensSent(targetChainId, to, amount);```
```BridgedOut(uint256 indexed dstChainId, address indexed bridgeUser, address indexed tokenReceiver, uint256 amount);```

## xWELL Token xERC20 Differences

xERC20 enforces a global rate limit per second on each bridge, meaning all bridge's buffers refill at the same speed once depleted. The xWELL implementation allows each bridge to have a different rate limit, allowing for more flexibility in the bridge setup. The xWELL implementation also allows for a bridge to be disabled, preventing any further minting from that bridge. This is useful if a bridge is compromised and needs to be disabled.

### Guardians

The xWELL token has a guardian system that allows for the token to be paused, which disables all bridging functionality. The guardian address is meant to be a multisig contract that requires a quorum of guardians to approve a transaction before it can be executed. The guardian system is meant to be used as a failsafe in case of a bridge compromise or other emergency. Once the guardian pauses the contract, then the pause timer starts. The pause duration is specified in the initializer of the xWELL token, and once the pause duration has passed, the contract automatically unpauses itself. Only the mint and burn functions of the token are disabled while the contract is paused.

The owner can change the pause duration, even while the contract is paused. This allows the owner to extend the pause duration if needed during an emergency situation.

The owner can only grant a new pause guardian if the contract is not paused, and the owner can unpause the contract, which enables them to assign a new pause guardian.

### Ownership

The contract is owned by the Temporal Governor on Base, and by the Moonwell Artemis Timelock on Moonwell. The owner can change the guardian address, and add, remove and change the rate limits on the bridges. The owner can also change the pause duration, even while the contract is paused.


### Constants

The xWELL token has a few constants that are used to configure the contract. These constants are:
- max rate limit per second: The maximum rate limit that a bridge can have is 10k tokens per second. This is used to prevent a bridge from having an unlimited rate limit.
- max pause duration: The maximum pause duration is 30 days. This is used to prevent the contract from being paused indefinitely.
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts-upgradeable
1 change: 1 addition & 0 deletions lib/zelt
Submodule zelt added at 447e7a
5 changes: 4 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
@forge-std/=lib/forge-std/src/
@openzeppelin-contracts/=lib/openzeppelin-contracts/
@openzeppelin/=lib/openzeppelin-contracts/
@openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/
@protocol=src/
@test=test/
@proposals=src/proposals/
@utils/=utils/
@utils/=utils/
@zelt/=lib/zelt/
Loading
Loading