Skip to content

Commit 81b9edd

Browse files
committed
Merge remote-tracking branch 'origin/main' into pr-340-work
2 parents 19ca7bf + 38bb40e commit 81b9edd

8 files changed

Lines changed: 159 additions & 71 deletions

File tree

.dockerignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.git
2+
.github
3+
.tsbuildinfo
4+
coverage
5+
node_modules
6+
**/node_modules
7+
shared/js
8+
solidity/artifacts
9+
solidity/coverage
10+
solidity/js
11+
solidity/ts/**/*.d.ts
12+
solidity/ts/**/*.d.ts.map
13+
solidity/ts/**/*.js
14+
solidity/ts/**/*.js.map
15+
solidity/ts/types/contractArtifact.ts
16+
solidity/types/contractArtifact.ts
17+
ui/dist
18+
ui/js
19+
ui/vendor
20+
ui/ts/**/*.d.ts
21+
ui/ts/**/*.d.ts.map
22+
ui/ts/**/*.js
23+
ui/ts/**/*.js.map
24+
ui/ts/abis.ts
25+
ui/ts/contractArtifact.ts
26+
ui/ts/deploymentArtifacts.ts
27+
ui/ts/deploymentsArtifacts.ts

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ concurrency:
1515
cancel-in-progress: true
1616

1717
env:
18-
BUN_VERSION: 1.3.11
18+
BUN_VERSION: 1.3.13
1919
FOUNDRY_VERSION: v1.5.1
2020

2121
jobs:

.github/workflows/ipfs-deploy.yml

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,97 @@
11
name: Build and Push to IPFS
22

33
on:
4+
workflow_run:
5+
workflows: [CI Gate]
6+
branches: [main]
7+
types: [completed]
48
push:
5-
# Publish `master` as Docker `latest` image.
6-
branches:
7-
- main
8-
9-
# Publish `v1.2.3` tags as releases.
109
tags:
1110
- v*
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: write
15+
packages: write
16+
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_sha || github.ref }}
19+
cancel-in-progress: true
1220

13-
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
1421
env:
22+
BUN_VERSION: 1.3.13
1523
REGISTRY: ghcr.io
1624

1725
jobs:
18-
# Push image to GitHub Packages.
19-
# See also https://docs.docker.com/docker-hub/builds/
20-
push:
26+
publish:
27+
name: Publish IPFS Image
2128
runs-on: ubuntu-latest
22-
if: github.event_name == 'push'
29+
if: github.event_name != 'workflow_run' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main')
2330

2431
steps:
25-
- uses: actions/checkout@v2
32+
- name: Checkout
33+
uses: actions/checkout@v7
34+
with:
35+
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
2636

27-
- name: Set IMAGE_TAG
28-
run: echo "IMAGE_TAG=$(echo ${{ github.repository }} | tr '[A-Z]' '[a-z]')" >> $GITHUB_ENV
37+
- name: Setup Bun
38+
uses: oven-sh/setup-bun@v2
39+
with:
40+
bun-version: ${{ env.BUN_VERSION }}
2941

30-
- name: Build image
42+
- name: Install dependencies
43+
run: |
44+
bun install --frozen-lockfile
45+
(cd ui && bun install --frozen-lockfile)
46+
(cd solidity && bun install --frozen-lockfile)
47+
48+
- name: Validate production build
49+
run: bun run ui:build:prod
50+
51+
- name: Set image metadata
3152
run: |
32-
docker build . --file ui/Dockerfile --tag $IMAGE_TAG
53+
IMAGE_NAME="${REGISTRY}/$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')"
54+
if [[ "${GITHUB_EVENT_NAME}" == "workflow_run" || "${GITHUB_REF_NAME}" == "main" ]]; then
55+
VERSION="latest"
56+
else
57+
VERSION="${GITHUB_REF_NAME#v}"
58+
fi
59+
echo "IMAGE_NAME=${IMAGE_NAME}" >> "$GITHUB_ENV"
60+
echo "IMAGE_VERSION=${VERSION}" >> "$GITHUB_ENV"
61+
echo "IMAGE_RELEASE_ID=${IMAGE_NAME}:${VERSION}" >> "$GITHUB_ENV"
62+
63+
- name: Build image
64+
run: docker build . --file ui/Dockerfile --build-arg BUN_VERSION="${BUN_VERSION}" --tag "${IMAGE_RELEASE_ID}"
3365

34-
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
3566
- name: Log in to the Container registry
36-
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
67+
uses: docker/login-action@v4
3768
with:
3869
registry: ${{ env.REGISTRY }}
3970
username: ${{ github.actor }}
4071
password: ${{ secrets.GITHUB_TOKEN }}
4172

4273
- name: Push image
43-
run: |
44-
IMAGE_ID=ghcr.io/$IMAGE_TAG
45-
46-
# Strip git ref prefix from version
47-
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
48-
49-
# Strip "v" prefix from tag name
50-
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
51-
52-
# Use Docker `latest` tag convention
53-
[ "$VERSION" == "master" ] && VERSION=latest
54-
55-
echo IMAGE_ID=$IMAGE_ID
56-
echo VERSION=$VERSION
57-
58-
docker tag $IMAGE_TAG $IMAGE_ID:$VERSION
59-
docker push $IMAGE_ID:$VERSION
60-
61-
# Make image reference available to subsequent steps
62-
echo "IMAGE_RELEASE_ID=$(echo $IMAGE_ID:$VERSION)" >> $GITHUB_ENV
74+
run: docker push "${IMAGE_RELEASE_ID}"
6375

6476
- name: Create a reference for IPFS hash
6577
if: github.ref_type == 'tag'
6678
run: |
67-
echo "IPFS_HASH=$(docker run --entrypoint /bin/sh $IMAGE_RELEASE_ID -c 'cat /ipfs_hash.txt')" >> $GITHUB_ENV
79+
IPFS_HASH=$(docker run --entrypoint /bin/sh "${IMAGE_RELEASE_ID}" -c 'cat /ipfs_hash.txt')
80+
echo "IPFS_HASH=${IPFS_HASH}" >> "$GITHUB_ENV"
6881
6982
- name: Create a release
7083
if: github.ref_type == 'tag'
7184
env:
7285
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7386
run: |
74-
# Markdown template for the release notes
7587
RELEASE_NOTE_TEMPLATE=$(cat << EOF
7688
#### IPFS Hash
7789
7890
\`\`\`
7991
$IPFS_HASH
8092
\`\`\`
8193
82-
You can view published versions of Rep Crowdsourcer through any IPFS Gateway
94+
You can view published versions of Zoltar through any IPFS gateway.
8395
8496
[ipfs://$IPFS_HASH](ipfs://$IPFS_HASH) __(Recommended)__
8597
_requires Brave Browser or IPFS Desktop_
@@ -90,7 +102,6 @@ jobs:
90102
EOF
91103
)
92104
93-
# Generate payload for creating a new release
94105
PAYLOAD_TEMPLATE=$(cat <<EOF
95106
{
96107
"name": "$GITHUB_REF_NAME",
@@ -102,8 +113,6 @@ jobs:
102113
EOF
103114
)
104115
105-
# Create a github release
106-
# https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
107116
REQUEST_DATA=$(echo "$PAYLOAD_TEMPLATE" | jq -c)
108117
RESPONSE=$(curl \
109118
--silent \
@@ -117,12 +126,10 @@ jobs:
117126
"https://api.github.com/repos/$GITHUB_REPOSITORY/releases"
118127
)
119128
120-
# Extract the response body and the appended http code
121129
RESPONSE_CODE=${RESPONSE: -3}
122130
RESPONSE_BODY=${RESPONSE//$RESPONSE_CODE/}
123131
124-
# Successful creation will return a status 201 (Created), otherwise show the error
125-
if [ "$RESPONSE_CODE" -ne 201 ]; then
132+
if [ "$RESPONSE_CODE" -ne 201 ]; then
126133
ERROR_MESSAGE=$(echo "$RESPONSE_BODY" | jq '.message')
127134
echo "HTTP $RESPONSE_CODE - $ERROR_MESSAGE"
128135
exit 1

docs/mainnet-deployment-addresses.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
{
1414
"id": "deploymentStatusOracle",
1515
"label": "Deployment Status Oracle",
16-
"address": "0x138aa911c7E0d63DD3C81e4675EC8A08883728b3"
16+
"address": "0xD262Bb8bBa927dD08a3fd3d6adcbAB9660B5F2e5"
1717
},
1818
{
1919
"id": "multicall3",
@@ -23,7 +23,7 @@
2323
{
2424
"id": "uniformPriceDualCapBatchAuctionFactory",
2525
"label": "UniformPriceDualCapBatchAuctionFactory",
26-
"address": "0x47A117D404C31b5CFF82883D40c0610404D26a60"
26+
"address": "0xbA605970da511b08539bcC4F77B54CF1Cd72783c"
2727
},
2828
{
2929
"id": "scalarOutcomes",
@@ -33,7 +33,7 @@
3333
{
3434
"id": "securityPoolUtils",
3535
"label": "SecurityPoolUtils",
36-
"address": "0x9E90338b17E1Fea80Cd356607EbB6eC46653fB24"
36+
"address": "0x04349f6A0302F32f8c87bb8555648AD77634343C"
3737
},
3838
{
3939
"id": "openOracle",
@@ -53,27 +53,27 @@
5353
{
5454
"id": "shareTokenFactory",
5555
"label": "ShareTokenFactory",
56-
"address": "0x253d011F3A0f46096A4756a439543E9Dab36AA23"
56+
"address": "0x95fB9708d8e54e057d2bdf027D6C43B586Ca898F"
5757
},
5858
{
5959
"id": "priceOracleManagerAndOperatorQueuerFactory",
6060
"label": "Price Oracle Manager Factory",
61-
"address": "0x38d22Ec4282621eeeBE4EBFf04E08b893dC020FF"
61+
"address": "0xAA71aD70f8bed84f0fd57D711f21fae8D6310354"
6262
},
6363
{
6464
"id": "securityPoolForker",
6565
"label": "Security Pool Forker",
66-
"address": "0x290BF23Dd1912AdEDBdfd7419b85605C66e3d24B"
66+
"address": "0x21547294899fc37CAfa9EA0d1231D3F0b9ABd1F7"
6767
},
6868
{
6969
"id": "escalationGameFactory",
7070
"label": "Escalation Game Factory",
71-
"address": "0x94A7FB6E5a8EDC6559B748aD4FEAd0Bc68f4fCfD"
71+
"address": "0x0f8E07792B60329dD8FFcbAc99577816c74c130F"
7272
},
7373
{
7474
"id": "securityPoolFactory",
7575
"label": "Security Pool Factory",
76-
"address": "0x0070464ef3Fb90B5D3e128e47D5ffB20e12f24E6"
76+
"address": "0x8d36A27ce150F7F7f4077dC84589Bd501fA363B5"
7777
}
7878
]
7979
}

docs/mainnet-deployment-addresses.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ These values are derived from the frozen mainnet protocol config, current contra
1515
| ID | Label | Expected Address |
1616
| --- | --- | --- |
1717
| proxyDeployer | Proxy Deployer | `0x7A0D94F55792C434d74a40883C6ed8545E406D12` |
18-
| deploymentStatusOracle | Deployment Status Oracle | `0x138aa911c7E0d63DD3C81e4675EC8A08883728b3` |
18+
| deploymentStatusOracle | Deployment Status Oracle | `0xD262Bb8bBa927dD08a3fd3d6adcbAB9660B5F2e5` |
1919
| multicall3 | Multicall3 | `0x77609e84c39893D5fB99049FE0F461aEB4F4Ec79` |
20-
| uniformPriceDualCapBatchAuctionFactory | UniformPriceDualCapBatchAuctionFactory | `0x47A117D404C31b5CFF82883D40c0610404D26a60` |
20+
| uniformPriceDualCapBatchAuctionFactory | UniformPriceDualCapBatchAuctionFactory | `0xbA605970da511b08539bcC4F77B54CF1Cd72783c` |
2121
| scalarOutcomes | ScalarOutcomes | `0x5890b011CF7E36d4Fee28Bac8B5be6f61C392a4C` |
22-
| securityPoolUtils | SecurityPoolUtils | `0x9E90338b17E1Fea80Cd356607EbB6eC46653fB24` |
22+
| securityPoolUtils | SecurityPoolUtils | `0x04349f6A0302F32f8c87bb8555648AD77634343C` |
2323
| openOracle | OpenOracle | `0x51DED022c087758c187ce636aa5f6adE6B919abB` |
2424
| zoltarQuestionData | ZoltarQuestionData | `0xeadF91d12F549786891350B3D535638713651207` |
2525
| zoltar | Zoltar | `0xd282Ae3cC11423c740afD608e715CD4e22831A29` |
26-
| shareTokenFactory | ShareTokenFactory | `0x253d011F3A0f46096A4756a439543E9Dab36AA23` |
27-
| priceOracleManagerAndOperatorQueuerFactory | Price Oracle Manager Factory | `0x38d22Ec4282621eeeBE4EBFf04E08b893dC020FF` |
28-
| securityPoolForker | Security Pool Forker | `0x290BF23Dd1912AdEDBdfd7419b85605C66e3d24B` |
29-
| escalationGameFactory | Escalation Game Factory | `0x94A7FB6E5a8EDC6559B748aD4FEAd0Bc68f4fCfD` |
30-
| securityPoolFactory | Security Pool Factory | `0x0070464ef3Fb90B5D3e128e47D5ffB20e12f24E6` |
26+
| shareTokenFactory | ShareTokenFactory | `0x95fB9708d8e54e057d2bdf027D6C43B586Ca898F` |
27+
| priceOracleManagerAndOperatorQueuerFactory | Price Oracle Manager Factory | `0xAA71aD70f8bed84f0fd57D711f21fae8D6310354` |
28+
| securityPoolForker | Security Pool Forker | `0x21547294899fc37CAfa9EA0d1231D3F0b9ABd1F7` |
29+
| escalationGameFactory | Escalation Game Factory | `0x0f8E07792B60329dD8FFcbAc99577816c74c130F` |
30+
| securityPoolFactory | Security Pool Factory | `0x8d36A27ce150F7F7f4077dC84589Bd501fA363B5` |
3131

3232
Security pool deployments are deterministic per pool input rather than globally fixed. Their addresses are derived from the deployed factory set plus parent universe, universe ID, question ID, and security multiplier.

solidity/contracts/peripherals/SecurityPool.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,8 @@ contract SecurityPool is ISecurityPool {
472472
// Complete Sets
473473
////////////////////////////////////////
474474
function createCompleteSet() external payable isOperational {
475-
// TODO, we want to be able to create complete sets in the children right away, figure accounting out
475+
// Child pools mint complete sets only after migration and truth-auction
476+
// accounting have restored `SystemState.Operational`.
476477
require(!isEscalationResolved(), 'question resolved');
477478
require(msg.value > 0, 'need eth');
478479
updateCollateralAmount();

solidity/ts/tests/peripherals.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,6 +2779,56 @@ describe('Peripherals Contract Test Suite', () => {
27792779
strictEqualTypeSafe(childVaultAfterRedeem.repDepositShare, 0n, 'operational child pool should allow redeemed ownership to clear')
27802780
})
27812781

2782+
test('child pool complete-set minting waits for settled fork accounting', async () => {
2783+
const forkThreshold = (await getTotalTheoreticalSupply(client, await getRepToken(client, securityPoolAddresses.securityPool))) / 20n
2784+
const passiveRepHolder = createWriteClient(mockWindow, TEST_ADDRESSES[6], 0)
2785+
await approveAndDepositRep(passiveRepHolder, 2n * forkThreshold, questionId)
2786+
const parentAllowance = repDeposit / 4n
2787+
await manipulatePriceOracleAndPerformOperation(client, mockWindow, securityPoolAddresses.priceOracleManagerAndOperatorQueuer, OperationType.SetSecurityBondsAllowance, client.account.address, parentAllowance)
2788+
const parentMintAmount = 5n * 10n ** 18n
2789+
await createCompleteSet(client, securityPoolAddresses.securityPool, parentMintAmount)
2790+
2791+
await triggerExternalForkForSecurityPool(undefined, 'complete-set child mint fork source')
2792+
await migrateRepToZoltar(client, securityPoolAddresses.securityPool, [QuestionOutcome.Yes])
2793+
await migrateVault(client, securityPoolAddresses.securityPool, QuestionOutcome.Yes)
2794+
2795+
const yesUniverse = getChildUniverseId(genesisUniverse, QuestionOutcome.Yes)
2796+
const yesSecurityPool = getSecurityPoolAddresses(securityPoolAddresses.securityPool, yesUniverse, questionId, securityMultiplier)
2797+
2798+
strictEqualTypeSafe(await getSystemState(client, yesSecurityPool.securityPool), SystemState.ForkMigration, 'child pool should wait in migration state before accounting is settled')
2799+
await assert.rejects(createCompleteSet(client, yesSecurityPool.securityPool, 1n), /not operational/)
2800+
2801+
await mockWindow.advanceTime(8n * 7n * DAY + DAY)
2802+
await startTruthAuction(client, yesSecurityPool.securityPool)
2803+
strictEqualTypeSafe(await getSystemState(client, yesSecurityPool.securityPool), SystemState.ForkTruthAuction, 'partially migrated child pool should price unsettled accounting through a truth auction')
2804+
const repAtFork = (await getSecurityPoolForkerForkData(client, securityPoolAddresses.securityPool)).auctionableRepAtFork
2805+
const migratedRep = await getMigratedRep(client, yesSecurityPool.securityPool)
2806+
const completeSetAmount = await getCompleteSetCollateralAmount(client, securityPoolAddresses.securityPool)
2807+
const expectedEthToBuy = completeSetAmount - (completeSetAmount * migratedRep) / repAtFork
2808+
strictEqualTypeSafe(expectedEthToBuy > 0n, true, 'partial migration should leave ETH for the truth auction to buy')
2809+
const auctionParticipant = createWriteClient(mockWindow, TEST_ADDRESSES[2], 0)
2810+
await participateAuction(auctionParticipant, yesSecurityPool.truthAuction, repAtFork / 4n, expectedEthToBuy)
2811+
await mockWindow.advanceTime(7n * DAY + DAY)
2812+
await finalizeTruthAuction(client, yesSecurityPool.securityPool)
2813+
strictEqualTypeSafe(await getSystemState(client, yesSecurityPool.securityPool), SystemState.Operational, 'child pool should become operational after truth-auction accounting settles')
2814+
strictEqualTypeSafe(await getQuestionOutcome(client, yesSecurityPool.securityPool), QuestionOutcome.None, 'unrelated fork should leave the child pool question unresolved')
2815+
strictEqualTypeSafe(await getTotalSecurityBondAllowance(client, yesSecurityPool.securityPool), parentAllowance, 'child pool should inherit parent security-bond capacity before minting new sets')
2816+
2817+
const childMintAmount = 1n * 10n ** 18n
2818+
await updateVaultFees(client, yesSecurityPool.securityPool, client.account.address)
2819+
const childCollateralBeforeMint = await getCompleteSetCollateralAmount(client, yesSecurityPool.securityPool)
2820+
const childShareSupplyBeforeMint = await getShareTokenSupply(client, yesSecurityPool.securityPool)
2821+
2822+
await createCompleteSet(client, yesSecurityPool.securityPool, childMintAmount)
2823+
2824+
const childCollateralAfterMint = await getCompleteSetCollateralAmount(client, yesSecurityPool.securityPool)
2825+
assert.ok(childCollateralAfterMint > childCollateralBeforeMint, 'child complete-set mint should increase collateral after fork accounting is settled')
2826+
assert.ok(childCollateralAfterMint <= childCollateralBeforeMint + childMintAmount, 'child complete-set mint should accrue fees before adding new collateral')
2827+
const updatedCollateralBeforeMint = childCollateralAfterMint - childMintAmount
2828+
const expectedMintedShares = updatedCollateralBeforeMint === 0n ? childMintAmount * PRICE_PRECISION : (childMintAmount * childShareSupplyBeforeMint) / updatedCollateralBeforeMint
2829+
strictEqualTypeSafe(await getShareTokenSupply(client, yesSecurityPool.securityPool), childShareSupplyBeforeMint + expectedMintedShares, 'child complete-set mint should add shares at the settled exchange rate')
2830+
})
2831+
27822832
test('can migrate escalation deposits before migrateVault', async () => {
27832833
const endTime = await getQuestionEndDate(client, questionId)
27842834
await mockWindow.setTime(endTime + 10000n)

ui/Dockerfile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
# App Setup: Install dependencies and build app
33
# ---------------------------------------------
44

5-
FROM oven/bun:1.3.9-alpine AS builder
5+
ARG BUN_VERSION=1.3.13
6+
7+
FROM oven/bun:${BUN_VERSION}-alpine AS builder
68

79
# git is required by preinstall hook scripts (link-shared-node-modules.mjs uses git rev-parse)
810
RUN apk add --no-cache git
@@ -13,15 +15,16 @@ RUN git init
1315
COPY ./scripts/ /source/scripts/
1416
COPY ./ui/scripts/ /source/ui/scripts/
1517

16-
# Install root dependencies
17-
COPY ./package.json ./bun.lock /source/
18-
RUN bun install --frozen-lockfile
19-
20-
# Shared package metadata and outputs for local package resolution
18+
# Shared package metadata and source for local package resolution
2119
COPY ./shared/package.json /source/shared/package.json
2220
COPY ./shared/tsconfig.json /source/shared/tsconfig.json
23-
COPY ./shared/js/ /source/shared/js/
2421
COPY ./shared/ts/ /source/shared/ts/
22+
RUN mkdir -p /source/shared/js
23+
24+
# Install root dependencies and build generated shared outputs from tracked source.
25+
COPY ./package.json ./bun.lock /source/
26+
RUN bun install --frozen-lockfile
27+
RUN bun run shared:build
2528

2629
# Install Solidity dependencies
2730
COPY ./solidity/package.json ./solidity/bun.lock /source/solidity/

0 commit comments

Comments
 (0)