Skip to content

Commit

Permalink
Merge branch 'master' into feat/multiname-management
Browse files Browse the repository at this point in the history
  • Loading branch information
zencephalon committed Nov 6, 2024
2 parents efe4b87 + ca413fe commit ea30df4
Show file tree
Hide file tree
Showing 49 changed files with 876 additions and 571 deletions.
128 changes: 128 additions & 0 deletions .github/workflows/file-size-checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
name: File Size Checker

# Add required permissions
permissions:
contents: read
pull-requests: write
statuses: write

on:
pull_request:
types: [opened, synchronize]

jobs:
check-file-sizes:
name: File Size Check
runs-on: ubuntu-latest

steps:
# - name: Setup environment
# run: |
# apt-get update
# apt-get install -y git bc

- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check file sizes
id: check-sizes
run: |
# Initialize variables for tracking findings
large_files=""
huge_files=""
# Get all files in the PR
echo "Files changed in PR:"
git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
for file in $(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}); do
if [ -f "$file" ]; then
size=$(stat -c%s "$file")
size_mb=$(echo "scale=2; $size/1048576" | bc)
echo "Checking $file: ${size_mb}MB"
# Check for files over 40MB
if (( $(echo "$size_mb > 40" | bc -l) )); then
huge_files="${huge_files}* ${file} (${size_mb}MB)\n"
# Check for files over 10MB
elif (( $(echo "$size_mb > 10" | bc -l) )); then
large_files="${large_files}* ${file} (${size_mb}MB)\n"
fi
fi
done
# Print findings for debugging
echo "Large files found:"
echo -e "$large_files"
echo "Huge files found:"
echo -e "$huge_files"
# Set outputs for use in next steps
echo "large_files<<EOF" >> $GITHUB_OUTPUT
echo -e "$large_files" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "huge_files<<EOF" >> $GITHUB_OUTPUT
echo -e "$huge_files" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Fail if huge files are found
if [ ! -z "$huge_files" ]; then
echo "❌ Files over 40MB found!"
exit 1
fi
- name: Update Status and Comment
if: always()
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const hugeFiles = `${{ steps.check-sizes.outputs.huge_files }}`;
const largeFiles = `${{ steps.check-sizes.outputs.large_files }}`;
try {
console.log('Repository:', context.payload.repository.name);
console.log('Owner:', context.payload.repository.owner.login);
console.log('SHA:', context.payload.pull_request.head.sha);
// Set status check that will be used by branch protection
await github.rest.repos.createCommitStatus({
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
sha: context.payload.pull_request.head.sha,
state: hugeFiles ? 'failure' : 'success',
context: 'File Size Check',
description: hugeFiles ? 'Files over 40MB found' : 'All files within size limits',
target_url: `https://github.com/${context.payload.repository.owner.login}/${context.payload.repository.name}/actions/runs/${context.runId}`
});
// Only comment if issues were found
if (hugeFiles || largeFiles) {
let comment = '## ⚠️ File Size Check Results\n\n';
if (hugeFiles) {
comment += '### 🚫 Files over 40MB (Not Allowed):\n' + hugeFiles + '\n';
comment += '**These files must be removed from git history before the PR can be merged.**\n\n';
}
if (largeFiles) {
comment += '### ⚠️ Large Files (Over 10MB):\n' + largeFiles + '\n';
comment += 'Consider reducing the size of these files if possible.\n';
}
await github.rest.issues.createComment({
issue_number: context.payload.pull_request.number,
owner: context.payload.repository.owner.login,
repo: context.payload.repository.name,
body: comment
});
}
} catch (error) {
console.error('Error:', error);
console.error('Context:', JSON.stringify(context.payload, null, 2));
core.setFailed(error.message);
}
45 changes: 0 additions & 45 deletions apps/base-docs/docs/security.md

This file was deleted.

51 changes: 51 additions & 0 deletions apps/base-docs/docs/security/app-blocklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: How to avoid getting your app flagged as malicious
slug: /security/app-blocklist
description: The Base bug bounty program and procedures for reporting vulnerabilities.
keywords:
[
Base,
Coinbase Wallet,
dapp,
app,
malicious warning,
browser,
dapp developer,
app developer,
best practice,
unblock,
remove warning,
]
hide_table_of_contents: true
---

# How to avoid getting your app flagged as malicious

---

Ensuring that your app is perceived as trustworthy and not flagged as malicious requires attention to best practices. Here’s a quick guide on how to build a secure and compliant app from day one

## Smart Contracts

- **Verify Source Code:** Ensure that the source code of your contracts is verified and publicly available on [block explorers](https://docs.base.org/docs/tools/block-explorers/).
- **Audit Your Contracts**: Having your contracts audited by a reputable firm is crucial. Publish the audit report and provide a reference link to it, so users can easily find it. Audits show that you’ve taken extra steps to secure your smart contracts.
- **Limit User Funds Exposure**: Design your contracts to minimize the exposure of user funds. Use efficient design to reduce any unnecessary risk. For example, request the minimum amount needed to fulfill the transaction.

---

## App Best Practices

- **Accessibility Across Regions**: Avoid geo-blocking or access restrictions that prevent certain regions or countries from accessing your app.
- **Consistent Web2 Behavior**: Avoid rapid or unexplained changes in UI that can make users feel uncertain about the app’s reliability.
- **Transparent Web3 Interactions**: Make sure your app’s web3 interactions are clear and match the UI actions. For example, a “Mint” button should clearly emit a mint transaction.
- **Standard Sign-in Methods**: Provide all standard connection methods for users to sign in, such as WalletConnect / WalletLink or popular browser extension wallets.

---

## Verification Request

Once you’ve implemented these best practices, consider submitting a verification request through the following [form](https://report.blockaid.io/). This step helps ensure that your app is recognized as safe and verified by trusted sources in the ecosystem.

By following these recommendations, you’ll significantly reduce the chances of your app being flagged as malicious and foster a secure and trustworthy environment for your users.

---
18 changes: 18 additions & 0 deletions apps/base-docs/docs/security/bounty.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Bug bounty
slug: /security/bounty
description: The Base bug bounty program
keywords:
[Base, HackerOne, bug bounty program, bug report, Base network, Bedrock, Optimism, open source]
hide_table_of_contents: true
---

# Bug bounty program

In line with our strategy of being the safest way for users to access crypto:

- Coinbase will be extending our [best-in-industry](https://www.coinbase.com/blog/celebrating-10-years-of-our-bug-bounty-program) million-dollar [HackerOne bug bounty program](https://hackerone.com/coinbase?type=team) to cover the Base network, the Base bridge contracts, and Base infrastructure.
- Coinbase will be working in tandem with OP Labs to harden the security guarantees of Bedrock and accelerate the timeline for decentralized fault-proofs on the [OP Stack](https://stack.optimism.io/).
- Coinbase's bug bounty program will run alongside Optimism's existing [Immunefi Bedrock bounty program](https://immunefi.com/bounty/optimism/) to support the open source [Bedrock](https://stack.optimism.io/docs/releases/bedrock/) OP Stack framework.

---
29 changes: 29 additions & 0 deletions apps/base-docs/docs/security/report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Report vulnerability
slug: /security/report
description: The Base procedures for reporting vulnerabilities.
keywords:
[
Base,
report vulnerability,
cybersecurity,
HackerOne,
Base network,
Bedrock,
Optimism,
vulnerability reporting,
crypto security,
open source,
]
hide_table_of_contents: true
---

# Reporting vulnerabilities

All potential vulnerability reports can be submitted via the [HackerOne](https://hackerone.com/coinbase) platform.

The HackerOne platform allows us to have a centralized and single reporting source for us to deliver optimized SLA's and results. All reports submitted to the platform are triaged around the clock by our team of Coinbase engineers with domain knowledge, assuring the best quality of review.

For more information on reporting vulnerabilities and our HackerOne bug bounty program, view our [security program policies](https://hackerone.com/coinbase?view_policy=true).

---
8 changes: 7 additions & 1 deletion apps/base-docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ module.exports = {
items: ['tokens/token-list', 'tokens/wallet'],
},
['contracts'],
['security'],
{
type: 'category',
label: 'Security',
collapsible: false,
collapsed: false,
items: ['security/bounty', 'security/report', 'security/app-blocklist'],
},
{
type: 'link',
label: 'Status',
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/(basenames)/name/[username]/ProfileProviders.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { BaseName } from '@coinbase/onchainkit/identity';
import { Basename } from '@coinbase/onchainkit/identity';
import AnalyticsProvider from 'apps/web/contexts/Analytics';
import UsernameProfileProvider from 'apps/web/src/components/Basenames/UsernameProfileContext';

Expand All @@ -9,7 +9,7 @@ const usernameProfileAnalyticContext = 'username_profile';

type ProfileProvidersProps = {
children: React.ReactNode;
username: BaseName;
username: Basename;
};

export default function ProfileProviders({ children, username }: ProfileProvidersProps) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BaseName } from '@coinbase/onchainkit/identity';
import { Basename } from '@coinbase/onchainkit/identity';
import ProfileProviders from 'apps/web/app/(basenames)/name/[username]/ProfileProviders';
import ErrorsProvider from 'apps/web/contexts/Errors';
import FrameBuilder from 'apps/web/src/components/Basenames/ConfigureFramesPageContent/FrameBuilder';
Expand All @@ -7,11 +7,11 @@ import { redirectIfNotNameOwner } from 'apps/web/src/utils/redirectIfNotNameOwne
import { formatDefaultUsername } from 'apps/web/src/utils/usernames';

export type ConfigureFramesProps = {
params: { username: BaseName };
params: { username: Basename };
};

export default async function ConfigureFrames({ params }: ConfigureFramesProps) {
let username = await formatDefaultUsername(decodeURIComponent(params.username) as BaseName);
let username = await formatDefaultUsername(decodeURIComponent(params.username) as Basename);
await redirectIfNotNameOwner(username);

return (
Expand Down
36 changes: 26 additions & 10 deletions apps/web/app/(basenames)/name/[username]/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import { isDevelopment } from 'apps/web/src/constants';
import {
formatBaseEthDomain,
getBasenameImage,
getChainForBasename,
USERNAME_DOMAINS,
UsernameTextRecordKeys,
} from 'apps/web/src/utils/usernames';
import { base, baseSepolia } from 'viem/chains';
import { USERNAME_L2_RESOLVER_ADDRESSES } from 'apps/web/src/addresses/usernames';
import { CLOUDFARE_IPFS_PROXY } from 'apps/web/src/utils/urls';
import { getIpfsGatewayUrl, IpfsUrl, IsValidIpfsUrl } from 'apps/web/src/utils/urls';
import { Basename } from '@coinbase/onchainkit/identity';
import { getCloudinaryMediaUrl } from 'apps/web/src/utils/images';
import { logger } from 'apps/web/src/utils/logger';
export const runtime = 'edge';

const size = {
Expand Down Expand Up @@ -63,24 +68,35 @@ export default async function OpenGraphImage(props: ImageRouteProps) {

const domainName = isDevelopment ? `http://localhost:3000` : 'https://www.base.org';
const profilePicture = getBasenameImage(username);
const chain = getChainForBasename(username as Basename);
let imageSource = domainName + profilePicture.src;

// NOTE: Do we want to fail if the name doesn't exists?
try {
const client = getBasenamePublicClient(base.id);
const avatar = await client.getEnsAvatar({
const client = getBasenamePublicClient(chain.id);
const avatar = await client.getEnsText({
name: username,
universalResolverAddress: USERNAME_L2_RESOLVER_ADDRESSES[base.id],
assetGatewayUrls: {
ipfs: CLOUDFARE_IPFS_PROXY,
},
key: UsernameTextRecordKeys.Avatar,
universalResolverAddress: USERNAME_L2_RESOLVER_ADDRESSES[chain.id],
});

// Satori Doesn't support webp
if (avatar && !avatar.endsWith('.webp')) {
if (!avatar) return;

// IPFS Resolution
if (IsValidIpfsUrl(avatar)) {
const ipfsUrl = getIpfsGatewayUrl(avatar as IpfsUrl);
if (ipfsUrl) {
imageSource = ipfsUrl;
}
} else {
imageSource = avatar;
}
} catch (error) {}

// Cloudinary resize / fetch
imageSource = getCloudinaryMediaUrl({ media: imageSource, format: 'png', width: 80 });
} catch (error) {
logger.error('Error fetching basename Avatar:', error);
}

return new ImageResponse(
(
Expand Down
Loading

0 comments on commit ea30df4

Please sign in to comment.