Skip to content

Commit 9a19a1c

Browse files
authored
Merge pull request #19 from bnb-chain/feat/audit-remediation-v2
feat: audit remediation v2 — SDK alignment with contract security fixes
1 parent 023fb13 commit 9a19a1c

20 files changed

Lines changed: 172 additions & 55 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ Thumbs.db
7373
**/node_modules/
7474

7575
.agent-data/
76-
.storage/
76+
.storage/
77+
78+
.env.*
79+
!.env.example

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Together, they enable agents to negotiate pricing, accept jobs, deliver work, an
9191
| **Escrow** | Payment tokens locked in the ERC-8183 contract until the job is settled |
9292
| **Negotiation** | Off-chain HTTP exchange where client and agent agree on price, terms, and deliverables. The agreed price is then used to set the on-chain budget. Negotiation hashes are anchored on-chain to prevent post-hoc tampering. |
9393
| **Service Price** | The agent's asking price for a job, configured via `SERVICE_PRICE` env var or `APEXConfig.service_price`. Returned in negotiation responses and `/status`. |
94-
| **Budget** | The amount of payment tokens a client locks in escrow for a job via `setBudget()` + `fund()`. The SDK automatically rejects jobs where `budget < service_price`. |
94+
| **Budget** | The agreed price set by the client via `setBudget()` and locked in escrow via `fund()`. The SDK automatically rejects jobs where `budget < service_price`. |
9595
| **Deliverable** | The work output, stored off-chain (IPFS); only the content hash goes on-chain |
9696
| **Evaluator** | A contract that verifies deliverables and triggers settlement (currently UMA OOv3) |
9797
| **Assertion** | An on-chain claim by the evaluator that the deliverable is valid, initiated by the provider after submitting work (provider pays the UMA bond) |

bnbagent/apex/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ contract. Inherits `ContractClientMixin` for nonce management and retries.
476476
| `create_job(provider, evaluator, expired_at, ...)` | Create a new job. Returns job ID + tx hash. |
477477
| `fund(job_id, expected_budget)` | Fund a job with BEP-20 tokens. |
478478
| `fund_with_permit(job_id, budget, opt_params, deadline, v, r, s)` | Fund a job using ERC-2612 permit (approve + fund in one tx). |
479-
| `set_budget(job_id, amount)` | Adjust the job budget. |
479+
| `set_budget(job_id, amount)` | Set the job budget (client-only). Provider proposes price via `/negotiate`. |
480480
| `set_provider(job_id, provider)` | Assign a provider agent. |
481481
| `submit(job_id, deliverable_hash, ...)` | Submit deliverables (provider). |
482482
| `complete(job_id)` | Mark job as complete (requester). |

bnbagent/apex/abis/APEXEvaluator.json

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@
8989
"name": "InvalidInitialization",
9090
"type": "error"
9191
},
92+
{
93+
"inputs": [
94+
{
95+
"internalType": "uint256",
96+
"name": "jobId",
97+
"type": "uint256"
98+
},
99+
{
100+
"internalType": "uint256",
101+
"name": "expiredAt",
102+
"type": "uint256"
103+
},
104+
{
105+
"internalType": "uint256",
106+
"name": "minRequired",
107+
"type": "uint256"
108+
}
109+
],
110+
"name": "JobExpiryTooSoon",
111+
"type": "error"
112+
},
92113
{
93114
"inputs": [
94115
{
@@ -461,6 +482,31 @@
461482
"name": "Paused",
462483
"type": "event"
463484
},
485+
{
486+
"anonymous": false,
487+
"inputs": [
488+
{
489+
"indexed": true,
490+
"internalType": "address",
491+
"name": "token",
492+
"type": "address"
493+
},
494+
{
495+
"indexed": true,
496+
"internalType": "address",
497+
"name": "to",
498+
"type": "address"
499+
},
500+
{
501+
"indexed": false,
502+
"internalType": "uint256",
503+
"name": "amount",
504+
"type": "uint256"
505+
}
506+
],
507+
"name": "TokensRescued",
508+
"type": "event"
509+
},
464510
{
465511
"anonymous": false,
466512
"inputs": [
@@ -1233,4 +1279,4 @@
12331279
"stateMutability": "pure",
12341280
"type": "function"
12351281
}
1236-
]
1282+
]

bnbagent/apex/abis/ERC8183.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,12 @@
342342
"name": "client",
343343
"type": "address"
344344
},
345+
{
346+
"indexed": true,
347+
"internalType": "address",
348+
"name": "provider",
349+
"type": "address"
350+
},
345351
{
346352
"indexed": false,
347353
"internalType": "uint256",
@@ -1407,4 +1413,4 @@
14071413
"stateMutability": "view",
14081414
"type": "function"
14091415
}
1410-
]
1416+
]

bnbagent/apex/client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def set_budget(
149149
amount: int,
150150
opt_params: bytes = b"",
151151
) -> dict[str, Any]:
152-
"""Set the budget for a job. Must be called before fund()."""
152+
"""Set the budget for a job (client-only). Provider proposes price via /negotiate."""
153153
fn = self.contract.functions.setBudget(job_id, amount, opt_params)
154154
return self._send_tx(fn)
155155

@@ -389,7 +389,7 @@ def get_job_funded_events(
389389
"""
390390
event_filter = {}
391391
if provider:
392-
event_filter["client"] = Web3.to_checksum_address(provider)
392+
event_filter["provider"] = Web3.to_checksum_address(provider)
393393

394394
logs = self.contract.events.JobFunded().get_logs(
395395
from_block=from_block,
@@ -401,6 +401,7 @@ def get_job_funded_events(
401401
{
402402
"jobId": log["args"]["jobId"],
403403
"client": log["args"]["client"],
404+
"provider": log["args"]["provider"],
404405
"amount": log["args"]["amount"],
405406
"blockNumber": log["blockNumber"],
406407
"transactionHash": log["transactionHash"].hex(),

examples/agent-server/scripts/register.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
from dotenv import load_dotenv
2424

2525
# Load .env from project root (one level up from scripts/)
26-
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
26+
env_file = os.path.basename(os.environ.get("ENV_FILE", ".env"))
27+
load_dotenv(Path(__file__).resolve().parent.parent / env_file)
2728

2829

2930
def main():

examples/agent-server/src/service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
from ddgs import DDGS
3434

3535
# Load .env from project root (one level up from src/)
36-
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
36+
env_file = os.path.basename(os.environ.get("ENV_FILE", ".env"))
37+
load_dotenv(Path(__file__).resolve().parent.parent / env_file)
3738

3839
# SDK imports
3940
from bnbagent.apex.config import APEXConfig

examples/agent-server/src/service_mount.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
from ddgs import DDGS
3333

3434
# Load .env from project root (one level up from src/)
35-
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
35+
env_file = os.path.basename(os.environ.get("ENV_FILE", ".env"))
36+
load_dotenv(Path(__file__).resolve().parent.parent / env_file)
3637

3738
# SDK imports
3839
from bnbagent.apex.config import APEXConfig

examples/client-workflow/scripts/discover_agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from dotenv import load_dotenv
2020

2121
# Load .env from demo root directory (.env next to scripts/)
22-
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
22+
env_file = os.path.basename(os.environ.get("ENV_FILE", ".env"))
23+
load_dotenv(Path(__file__).resolve().parent.parent / env_file)
2324

2425

2526
def discover_agents(name_filter: str = "") -> list:

0 commit comments

Comments
 (0)